@@ -18,6 +18,8 @@ use trans::build;
1818use trans:: common:: { self , Block } ;
1919use trans:: debuginfo:: DebugLoc ;
2020use trans:: machine;
21+ use trans:: type_of;
22+ use llvm;
2123
2224use 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