@@ -10,7 +10,7 @@ use rustc_middle::mir;
1010use rustc_middle:: mir:: tcx:: PlaceTy ;
1111use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf , TyAndLayout } ;
1212use rustc_middle:: ty:: { self , Ty } ;
13- use rustc_target:: abi:: { Abi , Align , FieldsShape , Int , TagEncoding } ;
13+ use rustc_target:: abi:: { Align , FieldsShape , Int , TagEncoding } ;
1414use rustc_target:: abi:: { VariantIdx , Variants } ;
1515
1616#[ derive( Copy , Clone , Debug ) ]
@@ -93,37 +93,15 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
9393 let effective_field_align = self . align . restrict_for_offset ( offset) ;
9494
9595 let mut simple = || {
96- let llval = match self . layout . abi {
97- _ if offset. bytes ( ) == 0 => {
98- // Unions and newtypes only use an offset of 0.
99- // Also handles the first field of Scalar, ScalarPair, and Vector layouts.
100- self . llval
101- }
102- Abi :: ScalarPair ( a, b)
103- if offset == a. size ( bx. cx ( ) ) . align_to ( b. align ( bx. cx ( ) ) . abi ) =>
104- {
105- // Offset matches second field.
106- let ty = bx. backend_type ( self . layout ) ;
107- bx. struct_gep ( ty, self . llval , 1 )
108- }
109- Abi :: Scalar ( _) | Abi :: ScalarPair ( ..) | Abi :: Vector { .. } if field. is_zst ( ) => {
110- // ZST fields are not included in Scalar, ScalarPair, and Vector layouts, so manually offset the pointer.
111- let byte_ptr = bx. pointercast ( self . llval , bx. cx ( ) . type_i8p ( ) ) ;
112- bx. gep ( bx. cx ( ) . type_i8 ( ) , byte_ptr, & [ bx. const_usize ( offset. bytes ( ) ) ] )
113- }
114- Abi :: Scalar ( _) | Abi :: ScalarPair ( ..) => {
115- // All fields of Scalar and ScalarPair layouts must have been handled by this point.
116- // Vector layouts have additional fields for each element of the vector, so don't panic in that case.
117- bug ! (
118- "offset of non-ZST field `{:?}` does not match layout `{:#?}`" ,
119- field,
120- self . layout
121- ) ;
122- }
123- _ => {
124- let ty = bx. backend_type ( self . layout ) ;
125- bx. struct_gep ( ty, self . llval , bx. cx ( ) . backend_field_index ( self . layout , ix) )
126- }
96+ let llval = if offset. bytes ( ) == 0 {
97+ self . llval
98+ } else {
99+ let byte_ptr = bx. pointercast ( self . llval , bx. cx ( ) . type_i8p ( ) ) ;
100+ // FIXME(eddyb) when can this not be `inbounds`? ZSTs?
101+ // (but since `offset` is larger than `0`, that would mean the
102+ // allocation the place points into has at least one byte, so
103+ // any possible offset in the layout *should* be in-bounds)
104+ bx. inbounds_gep ( bx. cx ( ) . type_i8 ( ) , byte_ptr, & [ bx. const_usize ( offset. bytes ( ) ) ] )
127105 } ;
128106 PlaceRef {
129107 // HACK(eddyb): have to bitcast pointers until LLVM removes pointee types.
@@ -189,6 +167,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
189167
190168 // Cast and adjust pointer.
191169 let byte_ptr = bx. pointercast ( self . llval , bx. cx ( ) . type_i8p ( ) ) ;
170+ // FIXME(eddyb) this should be `inbounds` (why not? ZSTs?)
192171 let byte_ptr = bx. gep ( bx. cx ( ) . type_i8 ( ) , byte_ptr, & [ offset] ) ;
193172
194173 // Finally, cast back to the type expected.
0 commit comments