@@ -111,23 +111,30 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
111111 . try_to_scalar_int ( )
112112 . map_err ( |dbg_val| err_ub ! ( InvalidTag ( dbg_val) ) ) ?
113113 . to_bits ( tag_layout. size ) ;
114+ // Ensure the tag is in its layout range. Codegen adds range metadata on the
115+ // discriminant load so we really have to make this UB.
116+ if !tag_scalar_layout. valid_range ( self ) . contains ( tag_bits) {
117+ throw_ub ! ( InvalidTag ( Scalar :: from_uint( tag_bits, tag_layout. size) ) )
118+ }
114119 // Cast bits from tag layout to discriminant layout.
115120 // After the checks we did above, this cannot fail, as
116121 // discriminants are int-like.
117122 let discr_val = self . int_to_int_or_float ( & tag_val, discr_layout) . unwrap ( ) ;
118123 let discr_bits = discr_val. to_scalar ( ) . to_bits ( discr_layout. size ) ?;
119- // Convert discriminant to variant index, and catch invalid discriminants.
124+ // Convert discriminant to variant index. Since we validated the tag against the
125+ // layout range above, this cannot fail.
120126 let index = match * ty. kind ( ) {
121127 ty:: Adt ( adt, _) => {
122- adt. discriminants ( * self . tcx ) . find ( |( _, var) | var. val == discr_bits)
128+ adt. discriminants ( * self . tcx ) . find ( |( _, var) | var. val == discr_bits) . unwrap ( )
123129 }
124130 ty:: Coroutine ( def_id, args) => {
125131 let args = args. as_coroutine ( ) ;
126- args. discriminants ( def_id, * self . tcx ) . find ( |( _, var) | var. val == discr_bits)
132+ args. discriminants ( def_id, * self . tcx )
133+ . find ( |( _, var) | var. val == discr_bits)
134+ . unwrap ( )
127135 }
128136 _ => span_bug ! ( self . cur_span( ) , "tagged layout for non-adt non-coroutine" ) ,
129- }
130- . ok_or_else ( || err_ub ! ( InvalidTag ( Scalar :: from_uint( tag_bits, tag_layout. size) ) ) ) ?;
137+ } ;
131138 // Return the cast value, and the index.
132139 index. 0
133140 }
@@ -174,13 +181,22 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
174181 let variants =
175182 ty. ty_adt_def ( ) . expect ( "tagged layout for non adt" ) . variants ( ) ;
176183 assert ! ( variant_index < variants. next_index( ) ) ;
184+ // This should imply that the tag is in its layout range.
185+ assert ! ( tag_scalar_layout. valid_range( self ) . contains( tag_bits) ) ;
186+
177187 if variant_index == untagged_variant {
178188 // The untagged variant can be in the niche range, but even then it
179- // is not a valid encoding.
189+ // is not a valid encoding. Codegen inserts an `assume` here
190+ // so we really have to make this UB.
180191 throw_ub ! ( InvalidTag ( Scalar :: from_uint( tag_bits, tag_layout. size) ) )
181192 }
182193 variant_index
183194 } else {
195+ // Ensure the tag is in its layout range. Codegen adds range metadata on
196+ // the discriminant load so we really have to make this UB.
197+ if !tag_scalar_layout. valid_range ( self ) . contains ( tag_bits) {
198+ throw_ub ! ( InvalidTag ( Scalar :: from_uint( tag_bits, tag_layout. size) ) )
199+ }
184200 untagged_variant
185201 }
186202 }
0 commit comments