Skip to content

Commit 1ac37d5

Browse files
committed
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
1 parent 2bdf4af commit 1ac37d5

File tree

3 files changed

+10
-10
lines changed

3 files changed

+10
-10
lines changed

src/librustc/middle/trans/build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,9 +655,9 @@ pub fn FastCall(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
655655
}
656656

657657
pub fn CallWithConv(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef],
658-
Conv: CallConv) -> ValueRef {
658+
Conv: CallConv, sret: bool) -> ValueRef {
659659
if cx.unreachable { return _UndefReturn(cx, Fn); }
660-
B(cx).call_with_conv(Fn, Args, Conv)
660+
B(cx).call_with_conv(Fn, Args, Conv, sret)
661661
}
662662

663663
pub fn AtomicFence(cx: @mut Block, order: AtomicOrdering) {

src/librustc/middle/trans/builder.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use lib::llvm::llvm;
1313
use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
1414
use lib::llvm::{Opcode, IntPredicate, RealPredicate, False};
1515
use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
16+
use lib::llvm::{StructRetAttribute};
1617
use middle::trans::base;
1718
use middle::trans::common::*;
1819
use middle::trans::machine::llalign_of_min;
@@ -778,14 +779,9 @@ impl Builder {
778779

779780
pub fn call(&self, llfn: ValueRef, args: &[ValueRef]) -> ValueRef {
780781
self.count_insn("call");
781-
782-
debug!("Call(llfn=%s, args=%?)",
783-
self.ccx.tn.val_to_str(llfn),
784-
args.map(|arg| self.ccx.tn.val_to_str(*arg)));
785-
786782
do args.as_imm_buf |ptr, len| {
787783
unsafe {
788-
llvm::LLVMBuildCall(self.llbuilder, llfn, ptr, len as c_uint, noname())
784+
llvm::LLVMBuildCall(self.llbuilder, llfn, ptr, len as c_uint, noname())
789785
}
790786
}
791787
}
@@ -801,12 +797,16 @@ impl Builder {
801797
}
802798

803799
pub fn call_with_conv(&self, llfn: ValueRef, args: &[ValueRef],
804-
conv: CallConv) -> ValueRef {
800+
conv: CallConv, sret: bool) -> ValueRef {
805801
self.count_insn("callwithconv");
806802
unsafe {
807803
let v = llvm::LLVMBuildCall(self.llbuilder, llfn, vec::raw::to_ptr(args),
808804
args.len() as c_uint, noname());
809805
lib::llvm::SetInstructionCallConv(v, conv);
806+
if sret {
807+
let return_slot = 1;
808+
llvm::LLVMAddInstrAttribute(v, return_slot, StructRetAttribute as c_uint);
809+
}
810810
v
811811
}
812812
}

src/librustc/middle/trans/foreign.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ pub fn trans_native_call(bcx: @mut Block,
266266
}
267267
};
268268

269-
let llforeign_retval = CallWithConv(bcx, llfn, llargs_foreign, cc);
269+
let llforeign_retval = CallWithConv(bcx, llfn, llargs_foreign, cc, fn_type.sret);
270270

271271
// If the function we just called does not use an outpointer,
272272
// store the result into the rust outpointer. Cast the outpointer

0 commit comments

Comments
 (0)