]>
Commit | Line | Data |
---|---|---|
ba9703b0 XL |
1 | use rustc_middle::mir::*; |
2 | use rustc_middle::ty::{self, TyCtxt}; | |
ff7c6d11 | 3 | |
9fa01778 | 4 | /// Returns `true` if this place is allowed to be less aligned |
ff7c6d11 XL |
5 | /// than its containing struct (because it is within a packed |
6 | /// struct). | |
dc9dc135 XL |
7 | pub fn is_disaligned<'tcx, L>( |
8 | tcx: TyCtxt<'tcx>, | |
9 | local_decls: &L, | |
10 | param_env: ty::ParamEnv<'tcx>, | |
ba9703b0 | 11 | place: Place<'tcx>, |
dc9dc135 XL |
12 | ) -> bool |
13 | where | |
14 | L: HasLocalDecls<'tcx>, | |
ff7c6d11 XL |
15 | { |
16 | debug!("is_disaligned({:?})", place); | |
17 | if !is_within_packed(tcx, local_decls, place) { | |
18 | debug!("is_disaligned({:?}) - not within packed", place); | |
dfeec247 | 19 | return false; |
ff7c6d11 XL |
20 | } |
21 | ||
532ac7d7 | 22 | let ty = place.ty(local_decls, tcx).ty; |
ff7c6d11 | 23 | match tcx.layout_raw(param_env.and(ty)) { |
a1dfa0c6 | 24 | Ok(layout) if layout.align.abi.bytes() == 1 => { |
ff7c6d11 XL |
25 | // if the alignment is 1, the type can't be further |
26 | // disaligned. | |
27 | debug!("is_disaligned({:?}) - align = 1", place); | |
28 | false | |
29 | } | |
30 | _ => { | |
31 | debug!("is_disaligned({:?}) - true", place); | |
32 | true | |
33 | } | |
34 | } | |
35 | } | |
36 | ||
ba9703b0 | 37 | fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: Place<'tcx>) -> bool |
dc9dc135 XL |
38 | where |
39 | L: HasLocalDecls<'tcx>, | |
ff7c6d11 | 40 | { |
e74abb32 XL |
41 | let mut cursor = place.projection.as_ref(); |
42 | while let &[ref proj_base @ .., elem] = cursor { | |
e1599b0c | 43 | cursor = proj_base; |
416331ca | 44 | |
e1599b0c | 45 | match elem { |
ff7c6d11 XL |
46 | // encountered a Deref, which is ABI-aligned |
47 | ProjectionElem::Deref => break, | |
48 | ProjectionElem::Field(..) => { | |
74b04a01 | 49 | let ty = Place::ty_from(place.local, proj_base, local_decls, tcx).ty; |
e74abb32 | 50 | match ty.kind { |
dfeec247 | 51 | ty::Adt(def, _) if def.repr.packed() => return true, |
ff7c6d11 XL |
52 | _ => {} |
53 | } | |
54 | } | |
55 | _ => {} | |
56 | } | |
ff7c6d11 XL |
57 | } |
58 | ||
59 | false | |
60 | } |