@@ -538,8 +538,8 @@ pub fn compare_scalar_values<'a>(
538
538
// We don't need to do actual comparisons for nil.
539
539
// () == () holds but () < () does not.
540
540
match op {
541
- ast:: BiEq | ast:: BiLe | ast:: BiGe => return C_i1 ( cx. ccx ( ) , true ) ,
542
- ast:: BiNe | ast:: BiLt | ast:: BiGt => return C_i1 ( cx. ccx ( ) , false ) ,
541
+ ast:: BiEq | ast:: BiLe | ast:: BiGe => return C_bool ( cx. ccx ( ) , true ) ,
542
+ ast:: BiNe | ast:: BiLt | ast:: BiGt => return C_bool ( cx. ccx ( ) , false ) ,
543
543
// refinements would be nice
544
544
_ => die ( cx)
545
545
}
@@ -958,10 +958,42 @@ pub fn need_invoke(bcx: &Block) -> bool {
958
958
959
959
pub fn load_if_immediate ( cx : & Block , v : ValueRef , t : ty:: t ) -> ValueRef {
960
960
let _icx = push_ctxt ( "load_if_immediate" ) ;
961
- if type_is_immediate ( cx. ccx ( ) , t) { return Load ( cx, v) ; }
961
+ if type_is_immediate ( cx. ccx ( ) , t) { return load_ty ( cx, v, t ) ; }
962
962
return v;
963
963
}
964
964
965
+ pub fn load_ty ( cx : & Block , ptr : ValueRef , t : ty:: t ) -> ValueRef {
966
+ /*!
967
+ * Helper for loading values from memory. Does the necessary conversion if
968
+ * the in-memory type differs from the type used for SSA values. Also
969
+ * handles various special cases where the type gives us better information
970
+ * about what we are loading.
971
+ */
972
+ if type_is_zero_size ( cx. ccx ( ) , t) {
973
+ C_undef ( type_of:: type_of ( cx. ccx ( ) , t) )
974
+ } else if ty:: type_is_bool ( t) {
975
+ Trunc ( cx, LoadRangeAssert ( cx, ptr, 0 , 2 , lib:: llvm:: False ) , Type :: i1 ( cx. ccx ( ) ) )
976
+ } else if ty:: type_is_char ( t) {
977
+ // a char is a unicode codepoint, and so takes values from 0
978
+ // to 0x10FFFF inclusive only.
979
+ LoadRangeAssert ( cx, ptr, 0 , 0x10FFFF + 1 , lib:: llvm:: False )
980
+ } else {
981
+ Load ( cx, ptr)
982
+ }
983
+ }
984
+
985
+ pub fn store_ty ( cx : & Block , v : ValueRef , dst : ValueRef , t : ty:: t ) {
986
+ /*!
987
+ * Helper for storing values in memory. Does the necessary conversion if
988
+ * the in-memory type differs from the type used for SSA values.
989
+ */
990
+ if ty:: type_is_bool ( t) {
991
+ Store ( cx, ZExt ( cx, v, Type :: i8 ( cx. ccx ( ) ) ) , dst) ;
992
+ } else {
993
+ Store ( cx, v, dst) ;
994
+ } ;
995
+ }
996
+
965
997
pub fn ignore_lhs ( _bcx : & Block , local : & ast:: Local ) -> bool {
966
998
match local. pat . node {
967
999
ast:: PatWild => true , _ => false
@@ -1013,7 +1045,7 @@ pub fn call_memcpy(cx: &Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef,
1013
1045
let dst_ptr = PointerCast ( cx, dst, Type :: i8p ( ccx) ) ;
1014
1046
let size = IntCast ( cx, n_bytes, ccx. int_type ) ;
1015
1047
let align = C_i32 ( ccx, align as i32 ) ;
1016
- let volatile = C_i1 ( ccx, false ) ;
1048
+ let volatile = C_bool ( ccx, false ) ;
1017
1049
Call ( cx, memcpy, [ dst_ptr, src_ptr, size, align, volatile] , [ ] ) ;
1018
1050
}
1019
1051
@@ -1058,7 +1090,7 @@ fn memzero(b: &Builder, llptr: ValueRef, ty: Type) {
1058
1090
let llzeroval = C_u8 ( ccx, 0 ) ;
1059
1091
let size = machine:: llsize_of ( ccx, ty) ;
1060
1092
let align = C_i32 ( ccx, llalign_of_min ( ccx, ty) as i32 ) ;
1061
- let volatile = C_i1 ( ccx, false ) ;
1093
+ let volatile = C_bool ( ccx, false ) ;
1062
1094
b. call ( llintrinsicfn, [ llptr, llzeroval, size, align, volatile] , [ ] ) ;
1063
1095
}
1064
1096
@@ -1282,9 +1314,14 @@ fn copy_args_to_allocas<'a>(fcx: &FunctionContext<'a>,
1282
1314
// Ties up the llstaticallocas -> llloadenv -> lltop edges,
1283
1315
// and builds the return block.
1284
1316
pub fn finish_fn < ' a > ( fcx : & ' a FunctionContext < ' a > ,
1285
- last_bcx : & ' a Block < ' a > ) {
1317
+ last_bcx : & ' a Block < ' a > ,
1318
+ retty : ty:: t ) {
1286
1319
let _icx = push_ctxt ( "finish_fn" ) ;
1287
1320
1321
+ // This shouldn't need to recompute the return type,
1322
+ // as new_fn_ctxt did it already.
1323
+ let substd_retty = retty. substp ( fcx. ccx . tcx ( ) , fcx. param_substs ) ;
1324
+
1288
1325
let ret_cx = match fcx. llreturn . get ( ) {
1289
1326
Some ( llreturn) => {
1290
1327
if !last_bcx. terminated . get ( ) {
@@ -1294,13 +1331,13 @@ pub fn finish_fn<'a>(fcx: &'a FunctionContext<'a>,
1294
1331
}
1295
1332
None => last_bcx
1296
1333
} ;
1297
- build_return_block ( fcx, ret_cx) ;
1334
+ build_return_block ( fcx, ret_cx, substd_retty ) ;
1298
1335
debuginfo:: clear_source_location ( fcx) ;
1299
1336
fcx. cleanup ( ) ;
1300
1337
}
1301
1338
1302
1339
// Builds the return block for a function.
1303
- pub fn build_return_block ( fcx : & FunctionContext , ret_cx : & Block ) {
1340
+ pub fn build_return_block ( fcx : & FunctionContext , ret_cx : & Block , retty : ty :: t ) {
1304
1341
// Return the value if this function immediate; otherwise, return void.
1305
1342
if fcx. llretptr . get ( ) . is_none ( ) || fcx. caller_expects_out_pointer {
1306
1343
return RetVoid ( ret_cx) ;
@@ -1318,13 +1355,16 @@ pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
1318
1355
retptr. erase_from_parent ( ) ;
1319
1356
}
1320
1357
1321
- retval
1358
+ if ty:: type_is_bool ( retty) {
1359
+ Trunc ( ret_cx, retval, Type :: i1 ( fcx. ccx ) )
1360
+ } else {
1361
+ retval
1362
+ }
1322
1363
}
1323
1364
// Otherwise, load the return value from the ret slot
1324
- None => Load ( ret_cx, fcx. llretptr . get ( ) . unwrap ( ) )
1365
+ None => load_ty ( ret_cx, fcx. llretptr . get ( ) . unwrap ( ) , retty )
1325
1366
} ;
1326
1367
1327
-
1328
1368
Ret ( ret_cx, retval) ;
1329
1369
}
1330
1370
@@ -1422,7 +1462,7 @@ pub fn trans_closure(ccx: &CrateContext,
1422
1462
}
1423
1463
1424
1464
// Insert the mandatory first few basic blocks before lltop.
1425
- finish_fn( & fcx, bcx) ;
1465
+ finish_fn( & fcx, bcx, output_type ) ;
1426
1466
}
1427
1467
1428
1468
// trans_fn: creates an LLVM function corresponding to a source language
@@ -1512,7 +1552,7 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
1512
1552
}
1513
1553
}
1514
1554
1515
- finish_fn( & fcx, bcx) ;
1555
+ finish_fn( & fcx, bcx, result_ty ) ;
1516
1556
}
1517
1557
1518
1558
fn trans_enum_def( ccx: & CrateContext , enum_definition: & ast:: EnumDef ,
0 commit comments