]>
Commit | Line | Data |
---|---|---|
ba9703b0 XL |
1 | use rustc_middle::mir::*; |
2 | use rustc_middle::ty::{self, TyCtxt}; | |
cdc7bbd5 | 3 | use rustc_target::abi::Align; |
ff7c6d11 | 4 | |
9fa01778 | 5 | /// Returns `true` if this place is allowed to be less aligned |
ff7c6d11 XL |
6 | /// than its containing struct (because it is within a packed |
7 | /// struct). | |
dc9dc135 XL |
8 | pub fn is_disaligned<'tcx, L>( |
9 | tcx: TyCtxt<'tcx>, | |
10 | local_decls: &L, | |
11 | param_env: ty::ParamEnv<'tcx>, | |
ba9703b0 | 12 | place: Place<'tcx>, |
dc9dc135 XL |
13 | ) -> bool |
14 | where | |
15 | L: HasLocalDecls<'tcx>, | |
ff7c6d11 XL |
16 | { |
17 | debug!("is_disaligned({:?})", place); | |
ee023bcb FG |
18 | let Some(pack) = is_within_packed(tcx, local_decls, place) else { |
19 | debug!("is_disaligned({:?}) - not within packed", place); | |
20 | return false; | |
cdc7bbd5 | 21 | }; |
ff7c6d11 | 22 | |
532ac7d7 | 23 | let ty = place.ty(local_decls, tcx).ty; |
94222f64 | 24 | match tcx.layout_of(param_env.and(ty)) { |
cdc7bbd5 XL |
25 | Ok(layout) if layout.align.abi <= pack => { |
26 | // If the packed alignment is greater or equal to the field alignment, the type won't be | |
27 | // further disaligned. | |
28 | debug!( | |
29 | "is_disaligned({:?}) - align = {}, packed = {}; not disaligned", | |
30 | place, | |
31 | layout.align.abi.bytes(), | |
32 | pack.bytes() | |
33 | ); | |
ff7c6d11 XL |
34 | false |
35 | } | |
36 | _ => { | |
37 | debug!("is_disaligned({:?}) - true", place); | |
38 | true | |
39 | } | |
40 | } | |
41 | } | |
42 | ||
cdc7bbd5 XL |
43 | fn is_within_packed<'tcx, L>( |
44 | tcx: TyCtxt<'tcx>, | |
45 | local_decls: &L, | |
46 | place: Place<'tcx>, | |
47 | ) -> Option<Align> | |
dc9dc135 XL |
48 | where |
49 | L: HasLocalDecls<'tcx>, | |
ff7c6d11 | 50 | { |
5869c6ff | 51 | for (place_base, elem) in place.iter_projections().rev() { |
e1599b0c | 52 | match elem { |
ff7c6d11 XL |
53 | // encountered a Deref, which is ABI-aligned |
54 | ProjectionElem::Deref => break, | |
55 | ProjectionElem::Field(..) => { | |
5869c6ff | 56 | let ty = place_base.ty(local_decls, tcx).ty; |
1b1a35ee | 57 | match ty.kind() { |
ee023bcb | 58 | ty::Adt(def, _) => return def.repr().pack, |
ff7c6d11 XL |
59 | _ => {} |
60 | } | |
61 | } | |
62 | _ => {} | |
63 | } | |
ff7c6d11 XL |
64 | } |
65 | ||
cdc7bbd5 | 66 | None |
ff7c6d11 | 67 | } |