@@ -18,6 +18,8 @@ use trans::build;
18
18
use trans:: common:: { self , Block } ;
19
19
use trans:: debuginfo:: DebugLoc ;
20
20
use trans:: machine;
21
+ use trans:: type_of;
22
+ use llvm;
21
23
22
24
use std:: ptr;
23
25
@@ -91,10 +93,23 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
91
93
const_ty)
92
94
} ,
93
95
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
+ } ,
98
113
mir:: Lvalue :: Projection ( ref projection) => {
99
114
let tr_base = self . trans_lvalue ( bcx, & projection. base ) ;
100
115
let projected_ty = tr_base. ty . projection_ty ( tcx, & projection. elem ) ;
0 commit comments