aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-12-08 16:34:16 -0800
committerGraydon Hoare <[email protected]>2010-12-08 16:34:16 -0800
commit652ae9f50e67610b482a2c99360737e1b8e8077b (patch)
treec2b64e13daa705e03a537b1546c031b22a7578d9 /src
parentFix boxed returns. (diff)
downloadrust-652ae9f50e67610b482a2c99360737e1b8e8077b.tar.xz
rust-652ae9f50e67610b482a2c99360737e1b8e8077b.zip
Fix structure returns harder.
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/trans.rs9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index e48c6936..ef0e7143 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -1403,6 +1403,15 @@ impure fn trans_call(@block_ctxt cx, @ast.expr f,
auto args_res = trans_args(f_res._0.bcx, args, fn_ty);
auto retval = args_res._0.build.FastCall(f_res._0.val, args_res._1);
+ // Structured returns come back as first-class values. This is nice for
+ // LLVM but wrong for us; we treat structured values by pointer in
+ // most of our code here. So spill it to an alloca.
+ if (typeck.type_is_structural(ret_ty)) {
+ auto local = args_res._0.build.Alloca(type_of(cx.fcx.ccx, ret_ty));
+ args_res._0.build.Store(retval, local);
+ retval = local;
+ }
+
// Retval doesn't correspond to anything really tangible in the frame, but
// it's a ref all the same, so we put a note here to drop it when we're
// done in this scope.