diff options
| author | Daniel Micay <danielmicay@gmail.com> | 2013-09-12 23:23:44 -0400 |
|---|---|---|
| committer | Daniel Micay <danielmicay@gmail.com> | 2013-09-13 12:34:25 -0400 |
| commit | 1ac37d50c0096f13604c7ca249517b76ff1f1802 (patch) | |
| tree | 291e2d02b264607b7008179fe0410b6c44290438 | |
| parent | 2bdf4af0120d61b7853eb09c630a01a0596add42 (diff) | |
| download | rust-1ac37d50c0096f13604c7ca249517b76ff1f1802.tar.gz rust-1ac37d50c0096f13604c7ca249517b76ff1f1802.zip | |
set sret attribute as needed on call instructions
Since function pointers do not carry along the function attributes with them in the type, this needs to be set on the call instruction itself. Closes #9152
| -rw-r--r-- | src/librustc/middle/trans/build.rs | 4 | ||||
| -rw-r--r-- | src/librustc/middle/trans/builder.rs | 14 | ||||
| -rw-r--r-- | src/librustc/middle/trans/foreign.rs | 2 |
3 files changed, 10 insertions, 10 deletions
diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index acec33f7004..11458eda585 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -655,9 +655,9 @@ pub fn FastCall(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef { } pub fn CallWithConv(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef], - Conv: CallConv) -> ValueRef { + Conv: CallConv, sret: bool) -> ValueRef { if cx.unreachable { return _UndefReturn(cx, Fn); } - B(cx).call_with_conv(Fn, Args, Conv) + B(cx).call_with_conv(Fn, Args, Conv, sret) } pub fn AtomicFence(cx: @mut Block, order: AtomicOrdering) { diff --git a/src/librustc/middle/trans/builder.rs b/src/librustc/middle/trans/builder.rs index 6a1acf68efa..349f14aefbc 100644 --- a/src/librustc/middle/trans/builder.rs +++ b/src/librustc/middle/trans/builder.rs @@ -13,6 +13,7 @@ use lib::llvm::llvm; use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect}; use lib::llvm::{Opcode, IntPredicate, RealPredicate, False}; use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef}; +use lib::llvm::{StructRetAttribute}; use middle::trans::base; use middle::trans::common::*; use middle::trans::machine::llalign_of_min; @@ -778,14 +779,9 @@ impl Builder { pub fn call(&self, llfn: ValueRef, args: &[ValueRef]) -> ValueRef { self.count_insn("call"); - - debug!("Call(llfn=%s, args=%?)", - self.ccx.tn.val_to_str(llfn), - args.map(|arg| self.ccx.tn.val_to_str(*arg))); - do args.as_imm_buf |ptr, len| { unsafe { - llvm::LLVMBuildCall(self.llbuilder, llfn, ptr, len as c_uint, noname()) + llvm::LLVMBuildCall(self.llbuilder, llfn, ptr, len as c_uint, noname()) } } } @@ -801,12 +797,16 @@ impl Builder { } pub fn call_with_conv(&self, llfn: ValueRef, args: &[ValueRef], - conv: CallConv) -> ValueRef { + conv: CallConv, sret: bool) -> ValueRef { self.count_insn("callwithconv"); unsafe { let v = llvm::LLVMBuildCall(self.llbuilder, llfn, vec::raw::to_ptr(args), args.len() as c_uint, noname()); lib::llvm::SetInstructionCallConv(v, conv); + if sret { + let return_slot = 1; + llvm::LLVMAddInstrAttribute(v, return_slot, StructRetAttribute as c_uint); + } v } } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 26968ce4881..681852b3bf2 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -266,7 +266,7 @@ pub fn trans_native_call(bcx: @mut Block, } }; - let llforeign_retval = CallWithConv(bcx, llfn, llargs_foreign, cc); + let llforeign_retval = CallWithConv(bcx, llfn, llargs_foreign, cc, fn_type.sret); // If the function we just called does not use an outpointer, // store the result into the rust outpointer. Cast the outpointer |
