]> git.lizzy.rs Git - rust.git/commitdiff
Fix ReturnPointer generation for void return types
authorSimonas Kazlauskas <git@kazlauskas.me>
Sat, 19 Dec 2015 14:51:52 +0000 (16:51 +0200)
committerSimonas Kazlauskas <git@kazlauskas.me>
Wed, 6 Jan 2016 11:57:52 +0000 (13:57 +0200)
Fixes #30480

src/librustc_trans/trans/mir/lvalue.rs

index b167633909a4a3bde6f5d02ddf6e22cefd8113cd..f7245879e2dcee6dee4e4e374a02f0bf7e83d92e 100644 (file)
@@ -18,6 +18,8 @@
 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 @@ pub fn trans_lvalue(&mut self,
                     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);