@@ -858,16 +858,25 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
858
858
}
859
859
860
860
fn gep ( & mut self , _typ : Type < ' gcc > , ptr : RValue < ' gcc > , indices : & [ RValue < ' gcc > ] ) -> RValue < ' gcc > {
861
- let mut result = ptr;
861
+ let ptr_type = ptr. get_type ( ) ;
862
+ let mut pointee_type = ptr. get_type ( ) ;
863
+ // NOTE: we cannot use array indexing here like in inbounds_gep because array indexing is
864
+ // always considered in bounds in GCC (TODO(antoyo): to be verified).
865
+ // So, we have to cast to a number.
866
+ let mut result = self . context . new_bitcast ( None , ptr, self . sizet_type ) ;
867
+ // FIXME(antoyo): if there were more than 1 index, this code is probably wrong and would
868
+ // require dereferencing the pointer.
862
869
for index in indices {
863
- result = self . context . new_array_access ( None , result, * index) . get_address ( None ) . to_rvalue ( ) ;
870
+ pointee_type = pointee_type. get_pointee ( ) . expect ( "pointee type" ) ;
871
+ let pointee_size = self . context . new_rvalue_from_int ( index. get_type ( ) , pointee_type. get_size ( ) as i32 ) ;
872
+ result = result + self . gcc_int_cast ( * index * pointee_size, self . sizet_type ) ;
864
873
}
865
- result
874
+ self . context . new_bitcast ( None , result, ptr_type )
866
875
}
867
876
868
877
fn inbounds_gep ( & mut self , _typ : Type < ' gcc > , ptr : RValue < ' gcc > , indices : & [ RValue < ' gcc > ] ) -> RValue < ' gcc > {
869
- // FIXME(antoyo): would be safer if doing the same thing (loop) as gep .
870
- // TODO(antoyo): specify inbounds somehow .
878
+ // NOTE: array indexing is always considered in bounds in GCC (TODO(antoyo): to be verified) .
879
+ // TODO: replace with a loop like gep .
871
880
match indices. len ( ) {
872
881
1 => {
873
882
self . context . new_array_access ( None , ptr, indices[ 0 ] ) . get_address ( None )
0 commit comments