]> git.lizzy.rs Git - rust.git/commitdiff
Apply packed and align restrictions to unions.
authorCameron Hart <cameron.hart@gmail.com>
Sun, 23 Jul 2017 21:54:48 +0000 (07:54 +1000)
committerCameron Hart <cameron.hart@gmail.com>
Sun, 23 Jul 2017 21:54:48 +0000 (07:54 +1000)
src/librustc_typeck/check/mod.rs
src/test/compile-fail/conflicting-repr-hints.rs
src/test/compile-fail/repr-packed-contains-align.rs

index 1a5ef9b3ba7e34ed6c1ea1fed9136619f9ab9a7b..74d46c1525caf44c7701249d75b34944fbc0d910 100644 (file)
@@ -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) {
@@ -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();
         }
     }
 }
@@ -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;
             }
index e4a9205409bf167024bd46d991e1244b4f472bd8..12ac8fb57b1f875beae0eca6359159cbdbdc0bbc 100644 (file)
@@ -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() {}
index c584dcf3e5993eacd8eeeb083f53d5a88d2386c4..78d43064ea3d2323be727bbd7854fc9bd0c08a08 100644 (file)
@@ -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() {}