Create ret_dest as late as possible in all code paths
This commit is contained in:
parent
55200e75da
commit
432635a9ea
@ -817,23 +817,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
|
|
||||||
// The arguments we'll be passing. Plus one to account for outptr, if used.
|
// The arguments we'll be passing. Plus one to account for outptr, if used.
|
||||||
let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize;
|
let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize;
|
||||||
let mut llargs = Vec::with_capacity(arg_count);
|
|
||||||
|
|
||||||
// Prepare the return value destination
|
|
||||||
let ret_dest = self.make_return_dest(
|
|
||||||
bx,
|
|
||||||
destination,
|
|
||||||
&fn_abi.ret,
|
|
||||||
&mut llargs,
|
|
||||||
intrinsic.is_some(),
|
|
||||||
target.is_some(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if intrinsic == Some(sym::caller_location) {
|
if intrinsic == Some(sym::caller_location) {
|
||||||
return if let Some(target) = target {
|
return if let Some(target) = target {
|
||||||
let location =
|
let location =
|
||||||
self.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info });
|
self.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info });
|
||||||
|
|
||||||
|
let mut llargs = Vec::with_capacity(arg_count);
|
||||||
|
let ret_dest =
|
||||||
|
self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs, true, true);
|
||||||
|
assert_eq!(llargs, []);
|
||||||
if let ReturnDest::IndirectOperand(tmp, _) = ret_dest {
|
if let ReturnDest::IndirectOperand(tmp, _) = ret_dest {
|
||||||
location.val.store(bx, tmp);
|
location.val.store(bx, tmp);
|
||||||
}
|
}
|
||||||
@ -847,6 +840,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
match intrinsic {
|
match intrinsic {
|
||||||
None | Some(sym::drop_in_place) => {}
|
None | Some(sym::drop_in_place) => {}
|
||||||
Some(intrinsic) => {
|
Some(intrinsic) => {
|
||||||
|
let mut llargs = Vec::with_capacity(1);
|
||||||
|
let ret_dest = self.make_return_dest(
|
||||||
|
bx,
|
||||||
|
destination,
|
||||||
|
&fn_abi.ret,
|
||||||
|
&mut llargs,
|
||||||
|
true,
|
||||||
|
target.is_some(),
|
||||||
|
);
|
||||||
let dest = match ret_dest {
|
let dest = match ret_dest {
|
||||||
_ if fn_abi.ret.is_indirect() => llargs[0],
|
_ if fn_abi.ret.is_indirect() => llargs[0],
|
||||||
ReturnDest::Nothing => bx.const_undef(bx.type_ptr()),
|
ReturnDest::Nothing => bx.const_undef(bx.type_ptr()),
|
||||||
@ -902,6 +904,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut llargs = Vec::with_capacity(arg_count);
|
||||||
|
let destination = target.as_ref().map(|&target| {
|
||||||
|
(self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs, false, true), target)
|
||||||
|
});
|
||||||
|
|
||||||
// Split the rust-call tupled arguments off.
|
// Split the rust-call tupled arguments off.
|
||||||
let (first_args, untuple) = if abi == Abi::RustCall && !args.is_empty() {
|
let (first_args, untuple) = if abi == Abi::RustCall && !args.is_empty() {
|
||||||
let (tup, args) = args.split_last().unwrap();
|
let (tup, args) = args.split_last().unwrap();
|
||||||
@ -1042,14 +1049,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
(_, Some(llfn)) => llfn,
|
(_, Some(llfn)) => llfn,
|
||||||
_ => span_bug!(span, "no instance or llfn for call"),
|
_ => span_bug!(span, "no instance or llfn for call"),
|
||||||
};
|
};
|
||||||
|
|
||||||
helper.do_call(
|
helper.do_call(
|
||||||
self,
|
self,
|
||||||
bx,
|
bx,
|
||||||
fn_abi,
|
fn_abi,
|
||||||
fn_ptr,
|
fn_ptr,
|
||||||
&llargs,
|
&llargs,
|
||||||
target.as_ref().map(|&target| (ret_dest, target)),
|
destination,
|
||||||
unwind,
|
unwind,
|
||||||
&copied_constant_arguments,
|
&copied_constant_arguments,
|
||||||
mergeable_succ,
|
mergeable_succ,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user