@@ -120,6 +120,7 @@ enum EnumCheckType<'tcx> {
120120 } ,
121121}
122122
123+ #[ derive( Debug , Copy , Clone ) ]
123124struct TyAndSize < ' tcx > {
124125 pub ty : Ty < ' tcx > ,
125126 pub size : Size ,
@@ -337,7 +338,7 @@ fn insert_direct_enum_check<'tcx>(
337338 let invalid_discr_block_data = BasicBlockData :: new ( None , false ) ;
338339 let invalid_discr_block = basic_blocks. push ( invalid_discr_block_data) ;
339340 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 (
341342 tcx,
342343 local_decls,
343344 block_data,
@@ -348,13 +349,34 @@ fn insert_direct_enum_check<'tcx>(
348349 source_info,
349350 ) ;
350351
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+
351371 // Branch based on the discriminant value.
352372 block_data. terminator = Some ( Terminator {
353373 source_info,
354374 kind : TerminatorKind :: SwitchInt {
355- discr : Operand :: Copy ( discr ) ,
375+ discr : Operand :: Copy ( discr_masked ) ,
356376 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) ) ,
358380 invalid_discr_block,
359381 ) ,
360382 } ,
@@ -371,7 +393,7 @@ fn insert_direct_enum_check<'tcx>(
371393 } ) ) ,
372394 expected : true ,
373395 target : new_block,
374- msg : Box :: new ( AssertKind :: InvalidEnumConstruction ( Operand :: Copy ( discr ) ) ) ,
396+ msg : Box :: new ( AssertKind :: InvalidEnumConstruction ( Operand :: Copy ( discr_masked ) ) ) ,
375397 // This calls panic_invalid_enum_construction, which is #[rustc_nounwind].
376398 // We never want to insert an unwind into unsafe code, because unwinding could
377399 // make a failing UB check turn into much worse UB when we start unwinding.
0 commit comments