As you say, the logic is convoluted. Let's simplify it rather than make
it more convoluted. One possibility would be to change || to | to avoid
the shortcut, and then
bool note = lastalign > curalign;
if (note)
curalign = lastalign;
I went with your suggestion in the attached v2. Regtested and
bootstrapped on s390x, x86 and ppc64le.
Regards
Robin
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index ccf9e4ccf0b..f9d1c17f8ef 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -2314,14 +2314,14 @@ 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;
+ if (note)
curalign = lastalign;
curalign /= BITS_PER_UNIT;
@@ -2366,25 +2366,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))
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 53b2b5b637d..40488585052 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -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,
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e7268d5ad18..f774c75228d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2794,6 +2794,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))