PR c/86453 - error: type variant differs by TYPE_PACKED in free_lang_data since r255469
authorMartin Sebor <msebor@redhat.com>
Thu, 12 Jul 2018 16:21:06 +0000 (16:21 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Thu, 12 Jul 2018 16:21:06 +0000 (10:21 -0600)
gcc/ChangeLog:

PR c/86453
* attribs.c (decl_attributes): Reject conflicting attributes before
calling attribute handlers.

gcc/testsuite/ChangeLog:

PR c/86453
* c-c++-common/Wattributes.c: Adjust.
* gcc.dg/Wattributes-10.c: New test.
* g++.dg/Wattributes-3.C: Adjust.
* gcc.dg/Wattributes-6.c: Adjust.
* gcc.dg/pr18079.c: Adjust.
* gcc.dg/torture/pr42363.c: Adjust.

From-SVN: r262596

gcc/ChangeLog
gcc/attribs.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wattributes.c
gcc/testsuite/g++.dg/Wattributes-3.C
gcc/testsuite/gcc.dg/Wattributes-10.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wattributes-6.c
gcc/testsuite/gcc.dg/pr18079.c
gcc/testsuite/gcc.dg/torture/pr42363.c

index ec22e9356114e427f2a2bf83c2df41e77879a625..7e24d18175ac7e47bfa6defe3b032c57a3501160 100644 (file)
@@ -1,3 +1,9 @@
+2018-07-12  Martin Sebor  <msebor@redhat.com>
+
+       PR c/86453
+       * attribs.c (decl_attributes): Reject conflicting attributes before
+       calling attribute handlers.
+
 2018-07-12  Jan Hubicka  <hubicka@ucw.cz>
 
        * dumpfile.c (gcc::dump_manager::get_dump_file_name): Add PART
index bfadf124dcb0f682c32400be7b94d41c84c4dce9..efc879ba47674f606231213ee210fc93ae7a64a3 100644 (file)
@@ -672,6 +672,35 @@ decl_attributes (tree *node, tree attributes, int flags,
 
       bool no_add_attrs = false;
 
+      /* Check for exclusions with other attributes on the current
+        declation as well as the last declaration of the same
+        symbol already processed (if one exists).  Detect and
+        reject incompatible attributes.  */
+      bool built_in = flags & ATTR_FLAG_BUILT_IN;
+      if (spec->exclude
+         && (flag_checking || !built_in))
+       {
+         /* Always check attributes on user-defined functions.
+            Check them on built-ins only when -fchecking is set.
+            Ignore __builtin_unreachable -- it's both const and
+            noreturn.  */
+
+         if (!built_in
+             || !DECL_P (*anode)
+             || (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE
+                 && (DECL_FUNCTION_CODE (*anode)
+                     != BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE)))
+           {
+             bool no_add = diag_attr_exclusions (last_decl, *anode, name, spec);
+             if (!no_add && anode != node)
+               no_add = diag_attr_exclusions (last_decl, *node, name, spec);
+             no_add_attrs |= no_add;
+           }
+       }
+
+      if (no_add_attrs)
+       continue;
+
       if (spec->handler != NULL)
        {
          int cxx11_flag =
@@ -695,33 +724,6 @@ decl_attributes (tree *node, tree attributes, int flags,
            returned_attrs = chainon (ret, returned_attrs);
        }
 
-      /* If the attribute was successfully handled on its own and is
-        about to be added check for exclusions with other attributes
-        on the current declation as well as the last declaration of
-        the same symbol already processed (if one exists).  */
-      bool built_in = flags & ATTR_FLAG_BUILT_IN;
-      if (spec->exclude
-         && !no_add_attrs
-         && (flag_checking || !built_in))
-       {
-         /* Always check attributes on user-defined functions.
-            Check them on built-ins only when -fchecking is set.
-            Ignore __builtin_unreachable -- it's both const and
-            noreturn.  */
-
-         if (!built_in
-             || !DECL_P (*anode)
-             || (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE
-                 && (DECL_FUNCTION_CODE (*anode)
-                     != BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE)))
-           {
-             bool no_add = diag_attr_exclusions (last_decl, *anode, name, spec);
-             if (!no_add && anode != node)
-               no_add = diag_attr_exclusions (last_decl, *node, name, spec);
-             no_add_attrs |= no_add;
-           }
-       }
-
       /* Layout the decl in case anything changed.  */
       if (spec->type_required && DECL_P (*node)
          && (VAR_P (*node)
index d524e0d633d0ff1e988f9d2663be5a436bbfb729..7e8c380a691819f75688582857286361fab1dc0a 100644 (file)
@@ -1,3 +1,13 @@
+2018-07-12  Martin Sebor  <msebor@redhat.com>
+
+       PR c/86453
+       * c-c++-common/Wattributes.c: Adjust.
+       * gcc.dg/Wattributes-10.c: New test.
+       * g++.dg/Wattributes-3.C: Adjust.
+       * gcc.dg/Wattributes-6.c: Adjust.
+       * gcc.dg/pr18079.c: Adjust.
+       * gcc.dg/torture/pr42363.c: Adjust.
+
 2018-07-12  Julia Koval  <julia.koval@intel.com>
 
         * gcc.target/i386/avx512vl-vpclmulqdq-2.c: Remove 128bit
index 40a29856ec657cb87b3fcc9d52504684e1581a78..6925d4eaacdee35c8001bb3ac8e1368e805cbc78 100644 (file)
@@ -39,13 +39,13 @@ PackedPacked { int i; };
    aligned and packed on a function declaration.  */
 
 void ATTR ((aligned (8), packed))
-faligned8_1 (void);           /* { dg-warning ".packed. attribute ignored" } */
+faligned8_1 (void);           /* { dg-warning "ignoring attribute .packed. because it conflicts with attribute .aligned." } */
 
 void ATTR ((aligned (8)))
-faligned8_2 (void);           /* { dg-message "previous declaration here" "" { xfail *-*-* } } */
+faligned8_2 (void);           /* { dg-message "previous declaration here" } */
 
 void ATTR ((packed))
-faligned8_2 (void);           /* { dg-warning ".packed. attribute ignored" } */
+faligned8_2 (void);           /* { dg-warning "ignoring attribute .packed. because it conflicts with attribute .aligned." } */
 
 /* Exercise the handling of the mutually exclusive attributes
    always_inline and noinline (in that order).  */
index a70176b14b63fecd1355e07531492c60e89cd123..208ec6696551b9f0fbfc94c2854d480cc8781e27 100644 (file)
@@ -26,6 +26,8 @@ B::operator char () const { return 0; }
 
 ATTR ((__noinline__))
 B::operator int () const      // { dg-warning "ignoring attribute .noinline. because it conflicts with attribute .always_inline." }
+// { dg-warning "function might not be inlinable" "" { target *-*-* } .-1 }
+
 {
   return 0;
 }
@@ -43,6 +45,7 @@ C::operator char () { return 0; }
 
 ATTR ((__noinline__))
 C::operator short ()           // { dg-warning "ignoring attribute .noinline. because it conflicts with attribute .always_inline." }
+// { dg-warning "function might not be inlinable" "" { target *-*-* } .-1 }
 { return 0; }
 
 inline ATTR ((__noinline__))
diff --git a/gcc/testsuite/gcc.dg/Wattributes-10.c b/gcc/testsuite/gcc.dg/Wattributes-10.c
new file mode 100644 (file)
index 0000000..f88d7a2
--- /dev/null
@@ -0,0 +1,26 @@
+/* PR middle-end/86453 - error: type variant differs by TYPE_PACKED in
+   free_lang_data since r255469
+   { dg-do compile }
+   { dg-options "-Wall -ftrack-macro-expansion=0" } */
+
+#define A(expr) do { int a[1 - 2 * !(expr)]; (void)&a; } while (0)
+
+struct S
+{
+  int* __attribute__ ((aligned (16))) paligned;
+  int* __attribute__ ((packed)) ppacked;                  /* { dg-warning ".packed. attribute ignored for type .int \\\*." } */
+
+  int* __attribute__ ((aligned (16), packed)) qaligned;   /* { dg-warning "ignoring attribute .packed. because it conflicts with attribute .aligned." } */
+  int* __attribute__ ((packed, aligned (16))) qpacked;    /* { dg-warning ".packed. attribute ignored for type .int \\\*." } */
+} s;
+
+void test (void)
+{
+  /* Verify that attributes reported ignored really are ignored
+     and not applied.  */
+
+  A (__alignof__ (s.paligned) == 16);
+  A (__alignof__ (s.ppacked) < 16);
+  A (__alignof__ (s.qaligned) == 16);
+  A (__alignof__ (s.qpacked) == __alignof__ (s.paligned));
+}
index a260d018dcf10bb836c9bf43e86f403953e36f0e..b2ea7db183351dfece8b5b8c3904f4719a27aa37 100644 (file)
@@ -39,13 +39,13 @@ PackedPacked { int i; };
    aligned and packed on a function declaration.  */
 
 void ATTR ((aligned (8), packed))
-faligned8_1 (void);           /* { dg-warning ".packed. attribute ignored" } */
+faligned8_1 (void);           /* { dg-warning "ignoring attribute .packed. because it conflicts with attribute .aligned." } */
 
 void ATTR ((aligned (8)))
-faligned8_2 (void);           /* { dg-message "previous declaration here" "" { xfail *-*-* } } */
+faligned8_2 (void);           /* { dg-message "previous declaration here" } */
 
 void ATTR ((packed))
-faligned8_2 (void);           /* { dg-warning ".packed. attribute ignored" } */
+faligned8_2 (void);           /* { dg-warning "ignoring attribute .packed. because it conflicts with attribute .aligned." } */
 
 /* Exercise the handling of the mutually exclusive attributes
    always_inline and noinline (in that order).  */
index b84cdebde3f465abf938a0bc788680a750870d3f..a37dc1880b23cda73d7b1e3e0e93bcf4c1b9af34 100644 (file)
@@ -6,14 +6,14 @@ __attribute__ ((noinline))
 __attribute__ ((always_inline))
 int
 fn1 (int r)
-{ /* { dg-warning "attribute ignored due to conflict" } */
+{ /* { dg-warning "ignoring attribute .always_inline. because it conflicts with attribute .noinline." } */
   return r & 4;
 }
 
 __attribute__ ((noinline, always_inline))
 int
 fn2 (int r)
-{ /* { dg-warning "attribute ignored due to conflict" } */
+{ /* { dg-warning "ignoring attribute .always_inline. because it conflicts with attribute .noinline." } */
   return r & 4;
 }
 
@@ -21,13 +21,13 @@ __attribute__ ((always_inline))
 __attribute__ ((noinline))
 inline int
 fn3 (int r)
-{ /* { dg-warning "attribute ignored due to conflict" } */
+{ /* { dg-warning "ignoring attribute .noinline. because it conflicts with attribute .always_inline." } */
   return r & 8;
 }
 
 __attribute__ ((always_inline, noinline))
 inline int
 fn4 (int r)
-{ /* { dg-warning "attribute ignored due to conflict" } */
+{ /* { dg-warning "ignoring attribute .noinline. because it conflicts with attribute .always_inline." } */
   return r & 8;
 }
index ad0eac8ceed51efd6a35057415f2b33c7f7ef8c7..e4c3861a46d1f4437060b4f4b64943e19d05cd90 100644 (file)
@@ -54,7 +54,11 @@ static int __attribute__ ((pure, const, noreturn))
 barf (void) {
   /* { dg-warning "ignoring attribute .const." "const" { target *-*-* } .-1 } */
   /* { dg-warning "ignoring attribute .noreturn." "noreturn" { target *-*-* } .-2 } */
-} /* { dg-warning "does return" } */
+
+  /* The noreturn attribute is ignored so verify there is no warning
+     for returning from the function:
+     { dg-bogus "does return" } */
+}
 
 static int __attribute__ ((pure, const))
 bark (void) {   /* { dg-warning "ignoring attribute .const." } */