Skip to content

Commit 20ec53a

Browse files
committed
Fix ReturnPointer generation for void return types
Fixes #30480
1 parent 924bb1e commit 20ec53a

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

src/librustc_trans/trans/mir/lvalue.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use trans::build;
1818
use trans::common::{self, Block};
1919
use trans::debuginfo::DebugLoc;
2020
use trans::machine;
21+
use trans::type_of;
22+
use llvm;
2123

2224
use std::ptr;
2325

@@ -91,10 +93,23 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
9193
const_ty)
9294
},
9395
mir::Lvalue::ReturnPointer => {
94-
let return_ty = bcx.monomorphize(&self.mir.return_ty);
95-
let llval = fcx.get_ret_slot(bcx, return_ty, "return");
96-
LvalueRef::new_sized(llval, LvalueTy::from_ty(return_ty.unwrap()))
97-
}
96+
let fn_return_ty = bcx.monomorphize(&self.mir.return_ty);
97+
let return_ty = fn_return_ty.unwrap();
98+
let llval = if !common::return_type_is_void(bcx.ccx(), return_ty) {
99+
fcx.get_ret_slot(bcx, fn_return_ty, "")
100+
} else {
101+
// This is a void return; that is, there’s no place to store the value and
102+
// there cannot really be one (or storing into it doesn’t make sense, anyway).
103+
// Ergo, we return an undef ValueRef, so we do not have to special-case every
104+
// place using lvalues, and could use it the same way you use a regular
105+
// ReturnPointer LValue (i.e. store into it, load from it etc).
106+
let llty = type_of::type_of(bcx.ccx(), return_ty).ptr_to();
107+
unsafe {
108+
llvm::LLVMGetUndef(llty.to_ref())
109+
}
110+
};
111+
LvalueRef::new_sized(llval, LvalueTy::from_ty(return_ty))
112+
},
98113
mir::Lvalue::Projection(ref projection) => {
99114
let tr_base = self.trans_lvalue(bcx, &projection.base);
100115
let projected_ty = tr_base.ty.projection_ty(tcx, &projection.elem);

0 commit comments

Comments
 (0)