mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-03 12:13:43 +00:00
Auto merge of #43443 - bitshifter:issue-43317, r=nikomatsakis
Improve checking of conflicting packed and align representation hints on structs and unions. Fixes #43317 and improves #33626.
This commit is contained in:
commit
52a3309695
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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",
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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>,
|
||||
@ -1077,6 +1073,8 @@ fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let def = tcx.adt_def(def_id);
|
||||
def.destructor(tcx); // force the destructor to be evaluated
|
||||
check_representable(tcx, span, def_id);
|
||||
|
||||
check_packed(tcx, span, def_id);
|
||||
}
|
||||
|
||||
pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
|
||||
@ -1478,9 +1476,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,
|
||||
"type 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 type cannot transitively contain a `[repr(align)]` type").emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1493,7 +1497,7 @@ fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
return false;
|
||||
}
|
||||
match t.sty {
|
||||
ty::TyAdt(def, substs) if def.is_struct() => {
|
||||
ty::TyAdt(def, substs) if def.is_struct() || def.is_union() => {
|
||||
if tcx.adt_def(def.did).repr.align > 0 {
|
||||
return true;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -27,7 +27,32 @@ 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 type has conflicting packed and align representation hints
|
||||
|
||||
#[repr(packed)]
|
||||
#[repr(align(8))]
|
||||
struct G(i32); //~ ERROR type has conflicting packed and align representation hints
|
||||
|
||||
#[repr(align(8))]
|
||||
#[repr(packed)]
|
||||
struct H(i32); //~ ERROR type has conflicting packed and align representation hints
|
||||
|
||||
#[repr(packed, align(8))]
|
||||
union X { //~ ERROR type has conflicting packed and align representation hints
|
||||
i: i32
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
#[repr(align(8))]
|
||||
union Y { //~ ERROR type has conflicting packed and align representation hints
|
||||
i: i32
|
||||
}
|
||||
|
||||
#[repr(align(8))]
|
||||
#[repr(packed)]
|
||||
union Z { //~ ERROR type has conflicting packed and align representation hints
|
||||
i: i32
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -9,17 +9,53 @@
|
||||
// except according to those terms.
|
||||
#![feature(attr_literals)]
|
||||
#![feature(repr_align)]
|
||||
#![feature(untagged_unions)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[repr(align(16))]
|
||||
struct A(i32);
|
||||
struct SA(i32);
|
||||
|
||||
struct B(A);
|
||||
struct SB(SA);
|
||||
|
||||
#[repr(align(16))]
|
||||
union UA {
|
||||
i: i32
|
||||
}
|
||||
|
||||
union UB {
|
||||
a: UA
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
struct C(A); //~ ERROR: packed struct cannot transitively contain a `[repr(align)]` struct
|
||||
struct SC(SA); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
|
||||
|
||||
#[repr(packed)]
|
||||
struct D(B); //~ ERROR: packed struct cannot transitively contain a `[repr(align)]` struct
|
||||
struct SD(SB); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
|
||||
|
||||
#[repr(packed)]
|
||||
struct SE(UA); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
|
||||
|
||||
#[repr(packed)]
|
||||
struct SF(UB); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
|
||||
|
||||
#[repr(packed)]
|
||||
union UC { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
|
||||
a: UA
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
union UD { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
|
||||
n: UB
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
union UE { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
|
||||
a: SA
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
union UF { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
|
||||
n: SB
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
Loading…
Reference in New Issue
Block a user