Apply packed and align restrictions to unions.
This commit is contained in:
parent
200c4d0410
commit
5cccd6a9ee
3 changed files with 65 additions and 10 deletions
|
@ -1073,6 +1073,8 @@ fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
let def = tcx.adt_def(def_id);
|
let def = tcx.adt_def(def_id);
|
||||||
def.destructor(tcx); // force the destructor to be evaluated
|
def.destructor(tcx); // force the destructor to be evaluated
|
||||||
check_representable(tcx, span, def_id);
|
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) {
|
pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
|
||||||
|
@ -1477,11 +1479,11 @@ fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId)
|
||||||
if tcx.adt_def(def_id).repr.packed() {
|
if tcx.adt_def(def_id).repr.packed() {
|
||||||
if tcx.adt_def(def_id).repr.align > 0 {
|
if tcx.adt_def(def_id).repr.align > 0 {
|
||||||
struct_span_err!(tcx.sess, sp, E0587,
|
struct_span_err!(tcx.sess, sp, E0587,
|
||||||
"struct has conflicting packed and align representation hints").emit();
|
"type has conflicting packed and align representation hints").emit();
|
||||||
}
|
}
|
||||||
else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
|
else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
|
||||||
struct_span_err!(tcx.sess, sp, E0588,
|
struct_span_err!(tcx.sess, sp, E0588,
|
||||||
"packed struct cannot transitively contain a `[repr(align)]` struct").emit();
|
"packed type cannot transitively contain a `[repr(align)]` type").emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1495,7 +1497,7 @@ fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
match t.sty {
|
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 {
|
if tcx.adt_def(def.did).repr.align > 0 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,14 +28,31 @@ enum D { D }
|
||||||
struct E(i32);
|
struct E(i32);
|
||||||
|
|
||||||
#[repr(packed, align(8))]
|
#[repr(packed, align(8))]
|
||||||
struct F(i32); //~ ERROR struct has conflicting packed and align representation hints
|
struct F(i32); //~ ERROR type has conflicting packed and align representation hints
|
||||||
|
|
||||||
#[repr(packed)]
|
#[repr(packed)]
|
||||||
#[repr(align(8))]
|
#[repr(align(8))]
|
||||||
struct G(i32); //~ ERROR struct has conflicting packed and align representation hints
|
struct G(i32); //~ ERROR type has conflicting packed and align representation hints
|
||||||
|
|
||||||
#[repr(align(8))]
|
#[repr(align(8))]
|
||||||
#[repr(packed)]
|
#[repr(packed)]
|
||||||
struct H(i32); //~ ERROR struct has conflicting packed and align representation hints
|
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() {}
|
fn main() {}
|
||||||
|
|
|
@ -9,17 +9,53 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
#![feature(attr_literals)]
|
#![feature(attr_literals)]
|
||||||
#![feature(repr_align)]
|
#![feature(repr_align)]
|
||||||
|
#![feature(untagged_unions)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
#[repr(align(16))]
|
#[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)]
|
#[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)]
|
#[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() {}
|
fn main() {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue