Skip to content

Commit

Permalink
Apply packed and align restrictions to unions.
Browse files Browse the repository at this point in the history
  • Loading branch information
bitshifter committed Jul 23, 2017
1 parent 200c4d0 commit 5cccd6a
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 10 deletions.
8 changes: 5 additions & 3 deletions src/librustc_typeck/check/mod.rs
Expand Up @@ -1073,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) {
Expand Down Expand Up @@ -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.align > 0 {
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()) {
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();
}
}
}
Expand All @@ -1495,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;
}
Expand Down
23 changes: 20 additions & 3 deletions src/test/compile-fail/conflicting-repr-hints.rs
Expand Up @@ -28,14 +28,31 @@ enum D { D }
struct E(i32);

#[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(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(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() {}
44 changes: 40 additions & 4 deletions src/test/compile-fail/repr-packed-contains-align.rs
Expand Up @@ -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 SC(SA); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type

#[repr(packed)]
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)]
struct C(A); //~ ERROR: packed struct cannot transitively contain a `[repr(align)]` struct
union UE { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
a: SA
}

#[repr(packed)]
struct D(B); //~ ERROR: packed struct cannot transitively contain a `[repr(align)]` struct
union UF { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
n: SB
}

fn main() {}

0 comments on commit 5cccd6a

Please sign in to comment.