@@ -120,6 +120,7 @@ enum EnumCheckType<'tcx> {
120
120
} ,
121
121
}
122
122
123
+ #[ derive( Debug , Copy , Clone ) ]
123
124
struct TyAndSize < ' tcx > {
124
125
pub ty : Ty < ' tcx > ,
125
126
pub size : Size ,
@@ -337,7 +338,7 @@ fn insert_direct_enum_check<'tcx>(
337
338
let invalid_discr_block_data = BasicBlockData :: new ( None , false ) ;
338
339
let invalid_discr_block = basic_blocks. push ( invalid_discr_block_data) ;
339
340
let block_data = & mut basic_blocks[ current_block] ;
340
- let discr = insert_discr_cast_to_u128 (
341
+ let discr_place = insert_discr_cast_to_u128 (
341
342
tcx,
342
343
local_decls,
343
344
block_data,
@@ -348,13 +349,34 @@ fn insert_direct_enum_check<'tcx>(
348
349
source_info,
349
350
) ;
350
351
352
+ // Mask out the bits of the discriminant type.
353
+ let mask = discr. size . unsigned_int_max ( ) ;
354
+ let discr_masked =
355
+ local_decls. push ( LocalDecl :: with_source_info ( tcx. types . u128 , source_info) ) . into ( ) ;
356
+ let rvalue = Rvalue :: BinaryOp (
357
+ BinOp :: BitAnd ,
358
+ Box :: new ( (
359
+ Operand :: Copy ( discr_place) ,
360
+ Operand :: Constant ( Box :: new ( ConstOperand {
361
+ span : source_info. span ,
362
+ user_ty : None ,
363
+ const_ : Const :: Val ( ConstValue :: from_u128 ( mask) , tcx. types . u128 ) ,
364
+ } ) ) ,
365
+ ) ) ,
366
+ ) ;
367
+ block_data
368
+ . statements
369
+ . push ( Statement :: new ( source_info, StatementKind :: Assign ( Box :: new ( ( discr_masked, rvalue) ) ) ) ) ;
370
+
351
371
// Branch based on the discriminant value.
352
372
block_data. terminator = Some ( Terminator {
353
373
source_info,
354
374
kind : TerminatorKind :: SwitchInt {
355
- discr : Operand :: Copy ( discr ) ,
375
+ discr : Operand :: Copy ( discr_masked ) ,
356
376
targets : SwitchTargets :: new (
357
- discriminants. into_iter ( ) . map ( |discr| ( discr, new_block) ) ,
377
+ discriminants
378
+ . into_iter ( )
379
+ . map ( |discr_val| ( discr. size . truncate ( discr_val) , new_block) ) ,
358
380
invalid_discr_block,
359
381
) ,
360
382
} ,
@@ -371,7 +393,7 @@ fn insert_direct_enum_check<'tcx>(
371
393
} ) ) ,
372
394
expected : true ,
373
395
target : new_block,
374
- msg : Box :: new ( AssertKind :: InvalidEnumConstruction ( Operand :: Copy ( discr ) ) ) ,
396
+ msg : Box :: new ( AssertKind :: InvalidEnumConstruction ( Operand :: Copy ( discr_masked ) ) ) ,
375
397
// This calls panic_invalid_enum_construction, which is #[rustc_nounwind].
376
398
// We never want to insert an unwind into unsafe code, because unwinding could
377
399
// make a failing UB check turn into much worse UB when we start unwinding.
0 commit comments