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))