Skip to content

Commit

Permalink
Better detection of repr packed and align
Browse files Browse the repository at this point in the history
Fixes issue #43317.
  • Loading branch information
bitshifter committed Jul 23, 2017
1 parent 504328a commit 200c4d0
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 19 deletions.
1 change: 0 additions & 1 deletion src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2025,5 +2025,4 @@ register_diagnostics! {
E0490, // a value of type `..` is borrowed for too long
E0495, // cannot infer an appropriate lifetime due to conflicting requirements
E0566, // conflicting representation hints
E0587, // conflicting packed and align representation hints
}
8 changes: 0 additions & 8 deletions src/librustc/hir/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ impl<'a> CheckAttrVisitor<'a> {
};

let mut conflicting_reprs = 0;
let mut found_packed = false;
let mut found_align = false;

for word in words {

Expand Down Expand Up @@ -106,7 +104,6 @@ impl<'a> CheckAttrVisitor<'a> {
("attribute should be applied to struct or union",
"a struct or union")
} else {
found_packed = true;
continue
}
}
Expand All @@ -120,7 +117,6 @@ impl<'a> CheckAttrVisitor<'a> {
}
}
"align" => {
found_align = true;
if target != Target::Struct &&
target != Target::Union {
("attribute should be applied to struct or union",
Expand Down Expand Up @@ -150,10 +146,6 @@ impl<'a> CheckAttrVisitor<'a> {
span_warn!(self.sess, attr.span, E0566,
"conflicting representation hints");
}
if found_align && found_packed {
struct_span_err!(self.sess, attr.span, E0587,
"conflicting packed and align representation hints").emit();
}
}
}

Expand Down
18 changes: 10 additions & 8 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,11 +1063,7 @@ fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
check_simd(tcx, span, def_id);
}

// if struct is packed and not aligned, check fields for alignment.
// Checks for combining packed and align attrs on single struct are done elsewhere.
if tcx.adt_def(def_id).repr.packed() && tcx.adt_def(def_id).repr.align == 0 {
check_packed(tcx, span, def_id);
}
check_packed(tcx, span, def_id);
}

fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Expand Down Expand Up @@ -1478,9 +1474,15 @@ pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId
}

fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
if check_packed_inner(tcx, def_id, &mut Vec::new()) {
struct_span_err!(tcx.sess, sp, E0588,
"packed struct cannot transitively contain a `[repr(align)]` struct").emit();
if tcx.adt_def(def_id).repr.packed() {
if tcx.adt_def(def_id).repr.align > 0 {
struct_span_err!(tcx.sess, sp, E0587,
"struct has conflicting packed and align representation hints").emit();
}
else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
struct_span_err!(tcx.sess, sp, E0588,
"packed struct cannot transitively contain a `[repr(align)]` struct").emit();
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4663,6 +4663,7 @@ register_diagnostics! {
// but `{}` was found in the type `{}`
E0567, // auto traits can not have type parameters
E0568, // auto-traits can not have predicates,
E0587, // struct has conflicting packed and align representation hints
E0588, // packed struct cannot transitively contain a `[repr(align)]` struct
E0592, // duplicate definitions with name `{}`
// E0613, // Removed (merged with E0609)
Expand Down
12 changes: 10 additions & 2 deletions src/test/compile-fail/conflicting-repr-hints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,15 @@ enum D { D }
#[repr(C, packed)]
struct E(i32);

#[repr(packed, align(8))] //~ ERROR conflicting packed and align representation hints
struct F(i32);
#[repr(packed, align(8))]
struct F(i32); //~ ERROR struct has conflicting packed and align representation hints

#[repr(packed)]
#[repr(align(8))]
struct G(i32); //~ ERROR struct has conflicting packed and align representation hints

#[repr(align(8))]
#[repr(packed)]
struct H(i32); //~ ERROR struct has conflicting packed and align representation hints

fn main() {}

0 comments on commit 200c4d0

Please sign in to comment.