Skip to content

Commit 5cccd6a

Browse files
committed
Apply packed and align restrictions to unions.
1 parent 200c4d0 commit 5cccd6a

File tree

3 files changed

+65
-10
lines changed

3 files changed

+65
-10
lines changed

src/librustc_typeck/check/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,8 @@ fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
10731073
let def = tcx.adt_def(def_id);
10741074
def.destructor(tcx); // force the destructor to be evaluated
10751075
check_representable(tcx, span, def_id);
1076+
1077+
check_packed(tcx, span, def_id);
10761078
}
10771079

10781080
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)
14771479
if tcx.adt_def(def_id).repr.packed() {
14781480
if tcx.adt_def(def_id).repr.align > 0 {
14791481
struct_span_err!(tcx.sess, sp, E0587,
1480-
"struct has conflicting packed and align representation hints").emit();
1482+
"type has conflicting packed and align representation hints").emit();
14811483
}
14821484
else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
14831485
struct_span_err!(tcx.sess, sp, E0588,
1484-
"packed struct cannot transitively contain a `[repr(align)]` struct").emit();
1486+
"packed type cannot transitively contain a `[repr(align)]` type").emit();
14851487
}
14861488
}
14871489
}
@@ -1495,7 +1497,7 @@ fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
14951497
return false;
14961498
}
14971499
match t.sty {
1498-
ty::TyAdt(def, substs) if def.is_struct() => {
1500+
ty::TyAdt(def, substs) if def.is_struct() || def.is_union() => {
14991501
if tcx.adt_def(def.did).repr.align > 0 {
15001502
return true;
15011503
}

src/test/compile-fail/conflicting-repr-hints.rs

+20-3
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,31 @@ enum D { D }
2828
struct E(i32);
2929

3030
#[repr(packed, align(8))]
31-
struct F(i32); //~ ERROR struct has conflicting packed and align representation hints
31+
struct F(i32); //~ ERROR type has conflicting packed and align representation hints
3232

3333
#[repr(packed)]
3434
#[repr(align(8))]
35-
struct G(i32); //~ ERROR struct has conflicting packed and align representation hints
35+
struct G(i32); //~ ERROR type has conflicting packed and align representation hints
3636

3737
#[repr(align(8))]
3838
#[repr(packed)]
39-
struct H(i32); //~ ERROR struct has conflicting packed and align representation hints
39+
struct H(i32); //~ ERROR type has conflicting packed and align representation hints
40+
41+
#[repr(packed, align(8))]
42+
union X { //~ ERROR type has conflicting packed and align representation hints
43+
i: i32
44+
}
45+
46+
#[repr(packed)]
47+
#[repr(align(8))]
48+
union Y { //~ ERROR type has conflicting packed and align representation hints
49+
i: i32
50+
}
51+
52+
#[repr(align(8))]
53+
#[repr(packed)]
54+
union Z { //~ ERROR type has conflicting packed and align representation hints
55+
i: i32
56+
}
4057

4158
fn main() {}

src/test/compile-fail/repr-packed-contains-align.rs

+40-4
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,53 @@
99
// except according to those terms.
1010
#![feature(attr_literals)]
1111
#![feature(repr_align)]
12+
#![feature(untagged_unions)]
1213
#![allow(dead_code)]
1314

1415
#[repr(align(16))]
15-
struct A(i32);
16+
struct SA(i32);
1617

17-
struct B(A);
18+
struct SB(SA);
19+
20+
#[repr(align(16))]
21+
union UA {
22+
i: i32
23+
}
24+
25+
union UB {
26+
a: UA
27+
}
28+
29+
#[repr(packed)]
30+
struct SC(SA); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
31+
32+
#[repr(packed)]
33+
struct SD(SB); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
34+
35+
#[repr(packed)]
36+
struct SE(UA); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
37+
38+
#[repr(packed)]
39+
struct SF(UB); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
40+
41+
#[repr(packed)]
42+
union UC { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
43+
a: UA
44+
}
45+
46+
#[repr(packed)]
47+
union UD { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
48+
n: UB
49+
}
1850

1951
#[repr(packed)]
20-
struct C(A); //~ ERROR: packed struct cannot transitively contain a `[repr(align)]` struct
52+
union UE { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
53+
a: SA
54+
}
2155

2256
#[repr(packed)]
23-
struct D(B); //~ ERROR: packed struct cannot transitively contain a `[repr(align)]` struct
57+
union UF { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type
58+
n: SB
59+
}
2460

2561
fn main() {}

0 commit comments

Comments
 (0)