@@ -111,23 +111,29 @@ 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.
115+ if !tag_scalar_layout. valid_range ( self ) . contains ( tag_bits) {
116+ throw_ub ! ( InvalidTag ( Scalar :: from_uint( tag_bits, tag_layout. size) ) )
117+ }
114118 // Cast bits from tag layout to discriminant layout.
115119 // After the checks we did above, this cannot fail, as
116120 // discriminants are int-like.
117121 let discr_val = self . int_to_int_or_float ( & tag_val, discr_layout) . unwrap ( ) ;
118122 let discr_bits = discr_val. to_scalar ( ) . to_bits ( discr_layout. size ) ?;
119- // Convert discriminant to variant index, and catch invalid discriminants.
123+ // Convert discriminant to variant index. Since we validated the tag against the
124+ // layout range above, this cannot fail.
120125 let index = match * ty. kind ( ) {
121126 ty:: Adt ( adt, _) => {
122- adt. discriminants ( * self . tcx ) . find ( |( _, var) | var. val == discr_bits)
127+ adt. discriminants ( * self . tcx ) . find ( |( _, var) | var. val == discr_bits) . unwrap ( )
123128 }
124129 ty:: Coroutine ( def_id, args) => {
125130 let args = args. as_coroutine ( ) ;
126- args. discriminants ( def_id, * self . tcx ) . find ( |( _, var) | var. val == discr_bits)
131+ args. discriminants ( def_id, * self . tcx )
132+ . find ( |( _, var) | var. val == discr_bits)
133+ . unwrap ( )
127134 }
128135 _ => 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) ) ) ) ?;
136+ } ;
131137 // Return the cast value, and the index.
132138 index. 0
133139 }
@@ -174,13 +180,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
174180 let variants =
175181 ty. ty_adt_def ( ) . expect ( "tagged layout for non adt" ) . variants ( ) ;
176182 assert ! ( variant_index < variants. next_index( ) ) ;
183+ // This should imply that the tag is in its layout range.
184+ assert ! ( tag_scalar_layout. valid_range( self ) . contains( tag_bits) ) ;
185+
177186 if variant_index == untagged_variant {
178187 // The untagged variant can be in the niche range, but even then it
179188 // is not a valid encoding.
180189 throw_ub ! ( InvalidTag ( Scalar :: from_uint( tag_bits, tag_layout. size) ) )
181190 }
182191 variant_index
183192 } else {
193+ // Ensure the tag is in its layout range.
194+ if !tag_scalar_layout. valid_range ( self ) . contains ( tag_bits) {
195+ throw_ub ! ( InvalidTag ( Scalar :: from_uint( tag_bits, tag_layout. size) ) )
196+ }
184197 untagged_variant
185198 }
186199 }
0 commit comments