@@ -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 ,
@@ -338,7 +339,7 @@ fn insert_direct_enum_check<'tcx>(
338339 let invalid_discr_block_data = BasicBlockData :: new ( None , false ) ;
339340 let invalid_discr_block = basic_blocks. push ( invalid_discr_block_data) ;
340341 let block_data = & mut basic_blocks[ current_block] ;
341- let discr = insert_discr_cast_to_u128 (
342+ let discr_place = insert_discr_cast_to_u128 (
342343 tcx,
343344 local_decls,
344345 block_data,
@@ -349,13 +350,35 @@ fn insert_direct_enum_check<'tcx>(
349350 source_info,
350351 ) ;
351352
353+ // Mask out the bits of the discriminant type.
354+ let mask = discr. size . unsigned_int_max ( ) ;
355+ let discr_masked =
356+ local_decls. push ( LocalDecl :: with_source_info ( tcx. types . u128 , source_info) ) . into ( ) ;
357+ let rvalue = Rvalue :: BinaryOp (
358+ BinOp :: BitAnd ,
359+ Box :: new ( (
360+ Operand :: Copy ( discr_place) ,
361+ Operand :: Constant ( Box :: new ( ConstOperand {
362+ span : source_info. span ,
363+ user_ty : None ,
364+ const_ : Const :: Val ( ConstValue :: from_u128 ( mask) , tcx. types . u128 ) ,
365+ } ) ) ,
366+ ) ) ,
367+ ) ;
368+ block_data. statements . push ( Statement {
369+ source_info,
370+ kind : StatementKind :: Assign ( Box :: new ( ( discr_masked, rvalue) ) ) ,
371+ } ) ;
372+
352373 // Branch based on the discriminant value.
353374 block_data. terminator = Some ( Terminator {
354375 source_info,
355376 kind : TerminatorKind :: SwitchInt {
356- discr : Operand :: Copy ( discr ) ,
377+ discr : Operand :: Copy ( discr_masked ) ,
357378 targets : SwitchTargets :: new (
358- discriminants. into_iter ( ) . map ( |discr| ( discr, new_block) ) ,
379+ discriminants
380+ . into_iter ( )
381+ . map ( |discr_val| ( discr. size . truncate ( discr_val) , new_block) ) ,
359382 invalid_discr_block,
360383 ) ,
361384 } ,
@@ -372,7 +395,7 @@ fn insert_direct_enum_check<'tcx>(
372395 } ) ) ,
373396 expected : true ,
374397 target : new_block,
375- msg : Box :: new ( AssertKind :: InvalidEnumConstruction ( Operand :: Copy ( discr ) ) ) ,
398+ msg : Box :: new ( AssertKind :: InvalidEnumConstruction ( Operand :: Copy ( discr_masked ) ) ) ,
376399 // This calls panic_invalid_enum_construction, which is #[rustc_nounwind].
377400 // We never want to insert an unwind into unsafe code, because unwinding could
378401 // make a failing UB check turn into much worse UB when we start unwinding.
0 commit comments