diff options
| author | Ralf Jung <post@ralfj.de> | 2023-12-02 12:43:56 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2023-12-12 08:15:17 +0100 |
| commit | 9ef1e351665d9023483f4c281903848421319007 (patch) | |
| tree | 9e29a7f50383ccdd94c8bc599bc560d439ba9615 /compiler/rustc_codegen_ssa/src | |
| parent | b1613ebc432ae495ecfcfa822548390c250849a8 (diff) | |
reject projecting to fields whose offset we cannot compute
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/place.rs | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index a3fb3b9d783..c0bb3ac5661 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -99,6 +99,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { let offset = self.layout.fields.offset(ix); let effective_field_align = self.align.restrict_for_offset(offset); + // `simple` is called when we don't need to adjust the offset to + // the dynamic alignment of the field. let mut simple = || { let llval = match self.layout.abi { _ if offset.bytes() == 0 => { @@ -141,28 +143,21 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { }; // Simple cases, which don't need DST adjustment: - // * no metadata available - just log the case - // * known alignment - sized types, `[T]`, `str` or a foreign type + // * known alignment - sized types, `[T]`, `str` + // * offset 0 -- rounding up to alignment cannot change the offset // Note that looking at `field.align` is incorrect since that is not necessarily equal // to the dynamic alignment of the type. match field.ty.kind() { - _ if self.llextra.is_none() => { - debug!( - "unsized field `{}`, of `{:?}` has no metadata for adjustment", - ix, self.llval - ); - return simple(); - } _ if field.is_sized() => return simple(), - ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(), + ty::Slice(..) | ty::Str => return simple(), + _ if offset.bytes() == 0 => return simple(), _ => {} } // We need to get the pointer manually now. // We do this by casting to a `*i8`, then offsetting it by the appropriate amount. // We do this instead of, say, simply adjusting the pointer from the result of a GEP - // because the field may have an arbitrary alignment in the LLVM representation - // anyway. + // because the field may have an arbitrary alignment in the LLVM representation. // // To demonstrate: // |
