diff options
| author | Simonas Kazlauskas <git@kazlauskas.me> | 2015-12-19 16:51:52 +0200 |
|---|---|---|
| committer | Simonas Kazlauskas <git@kazlauskas.me> | 2016-01-06 13:57:52 +0200 |
| commit | 20ec53a0d38588044f32e35074c81e60b8d3a6ad (patch) | |
| tree | 862a0178669b72c682cacedb1c7a59276c076b0e | |
| parent | 924bb1e5ebeab4189c3c48dabae4915825b097b0 (diff) | |
| download | rust-20ec53a0d38588044f32e35074c81e60b8d3a6ad.tar.gz rust-20ec53a0d38588044f32e35074c81e60b8d3a6ad.zip | |
Fix ReturnPointer generation for void return types
Fixes #30480
| -rw-r--r-- | src/librustc_trans/trans/mir/lvalue.rs | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/librustc_trans/trans/mir/lvalue.rs b/src/librustc_trans/trans/mir/lvalue.rs index b167633909a..f7245879e2d 100644 --- a/src/librustc_trans/trans/mir/lvalue.rs +++ b/src/librustc_trans/trans/mir/lvalue.rs @@ -18,6 +18,8 @@ use trans::build; use trans::common::{self, Block}; use trans::debuginfo::DebugLoc; use trans::machine; +use trans::type_of; +use llvm; use std::ptr; @@ -91,10 +93,23 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { const_ty) }, mir::Lvalue::ReturnPointer => { - let return_ty = bcx.monomorphize(&self.mir.return_ty); - let llval = fcx.get_ret_slot(bcx, return_ty, "return"); - LvalueRef::new_sized(llval, LvalueTy::from_ty(return_ty.unwrap())) - } + let fn_return_ty = bcx.monomorphize(&self.mir.return_ty); + let return_ty = fn_return_ty.unwrap(); + let llval = if !common::return_type_is_void(bcx.ccx(), return_ty) { + fcx.get_ret_slot(bcx, fn_return_ty, "") + } else { + // This is a void return; that is, there’s no place to store the value and + // there cannot really be one (or storing into it doesn’t make sense, anyway). + // Ergo, we return an undef ValueRef, so we do not have to special-case every + // place using lvalues, and could use it the same way you use a regular + // ReturnPointer LValue (i.e. store into it, load from it etc). + let llty = type_of::type_of(bcx.ccx(), return_ty).ptr_to(); + unsafe { + llvm::LLVMGetUndef(llty.to_ref()) + } + }; + LvalueRef::new_sized(llval, LvalueTy::from_ty(return_ty)) + }, mir::Lvalue::Projection(ref projection) => { let tr_base = self.trans_lvalue(bcx, &projection.base); let projected_ty = tr_base.ty.projection_ty(tcx, &projection.elem); |
