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
This commit is contained in:
parent
2bdf4af012
commit
1ac37d50c0
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user