c-family: Copy DECL_USER_ALIGN even if DECL_ALIGN is similar.
authorRobin Dapp <rdapp@linux.ibm.com>
Tue, 15 Jun 2021 07:06:02 +0000 (09:06 +0200)
committerRobin Dapp <rdapp@linux.ibm.com>
Tue, 15 Jun 2021 07:12:55 +0000 (09:12 +0200)
When re-declaring a function with differing attributes DECL_USER_ALIGN
is usually not merged/copied when DECL_ALIGN is similar.  On s390 this
will cause a warning message not to be shown.  Similarly, we warned
about the wrong alignment when short-circuiting an alignment initialization in
common_handle_aligned_attribute ().

Fix this by copying DECL_USER_ALIGN even if DECL_ALIGN is similar as
well as getting rid of the short-circuited initialization.

gcc/c-family/ChangeLog:

* c-attribs.c (common_handle_aligned_attribute): Remove short
circuit and dead code.

gcc/c/ChangeLog:

* c-decl.c (merge_decls): Copy DECL_USER_ALIGN if DECL_ALIGN is
similar.

gcc/cp/ChangeLog:

* decl.c (duplicate_decls): Likewise.

gcc/c-family/c-attribs.c
gcc/c/c-decl.c
gcc/cp/decl.c

index 6bf492afcc0146f0dbb04206588c97f7bb187966..e60fb31d8c8ea16ad1ba7e88de29f12edf9d3d93 100644 (file)
@@ -2338,14 +2338,17 @@ common_handle_aligned_attribute (tree *node, tree name, tree args, int flags,
       *no_add_attrs = true;
     }
   else if (TREE_CODE (decl) == FUNCTION_DECL
-          && ((curalign = DECL_ALIGN (decl)) > bitalign
-              || ((lastalign = DECL_ALIGN (last_decl)) > bitalign)))
+          && (((curalign = DECL_ALIGN (decl)) > bitalign)
+              | ((lastalign = DECL_ALIGN (last_decl)) > bitalign)))
     {
       /* Either a prior attribute on the same declaration or one
         on a prior declaration of the same function specifies
         stricter alignment than this attribute.  */
-      bool note = lastalign != 0;
-      if (lastalign)
+      bool note = (lastalign > curalign
+                  || (lastalign == curalign
+                      && (DECL_USER_ALIGN (last_decl)
+                          > DECL_USER_ALIGN (decl))));
+      if (note)
        curalign = lastalign;
 
       curalign /= BITS_PER_UNIT;
@@ -2390,25 +2393,6 @@ common_handle_aligned_attribute (tree *node, tree name, tree args, int flags,
       This formally comes from the c++11 specification but we are
       doing it for the GNU attribute syntax as well.  */
     *no_add_attrs = true;
-  else if (!warn_if_not_aligned_p
-          && TREE_CODE (decl) == FUNCTION_DECL
-          && DECL_ALIGN (decl) > bitalign)
-    {
-      /* Don't warn for function alignment here if warn_if_not_aligned_p
-        is true.  It will be warned about later.  */
-      if (DECL_USER_ALIGN (decl))
-       {
-         /* Only reject attempts to relax/override an alignment
-            explicitly specified previously and accept declarations
-            that appear to relax the implicit function alignment for
-            the target.  Both increasing and increasing the alignment
-            set by -falign-functions setting is permitted.  */
-         error ("alignment for %q+D was previously specified as %d "
-                "and may not be decreased", decl,
-                DECL_ALIGN (decl) / BITS_PER_UNIT);
-         *no_add_attrs = true;
-       }
-    }
   else if (warn_if_not_aligned_p
           && TREE_CODE (decl) == FIELD_DECL
           && !DECL_C_BIT_FIELD (decl))
index a86792bbe06534dce40338302a99965ff7740be0..7cd13a593eb6b8cc3e862df309f067d34d12021f 100644 (file)
@@ -2620,6 +2620,9 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
          SET_DECL_ALIGN (newdecl, DECL_ALIGN (olddecl));
          DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
        }
+      else if (DECL_ALIGN (olddecl) == DECL_ALIGN (newdecl)
+              && DECL_USER_ALIGN (olddecl) != DECL_USER_ALIGN (newdecl))
+       DECL_USER_ALIGN (newdecl) = 1;
       if (DECL_WARN_IF_NOT_ALIGN (olddecl)
          > DECL_WARN_IF_NOT_ALIGN (newdecl))
        SET_DECL_WARN_IF_NOT_ALIGN (newdecl,
index f5596b689a210b5b97bb3dbedbe86a6980faef35..02772e94763fe524781329ce86e03a153aef7420 100644 (file)
@@ -2805,6 +2805,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
       SET_DECL_ALIGN (newdecl, DECL_ALIGN (olddecl));
       DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
     }
+  else if (DECL_ALIGN (olddecl) == DECL_ALIGN (newdecl)
+      && DECL_USER_ALIGN (olddecl) != DECL_USER_ALIGN (newdecl))
+    DECL_USER_ALIGN (newdecl) = 1;
+
   DECL_USER_ALIGN (olddecl) = DECL_USER_ALIGN (newdecl);
   if (DECL_WARN_IF_NOT_ALIGN (olddecl)
       > DECL_WARN_IF_NOT_ALIGN (newdecl))