My enhancement to improve the detection of attribute collisions introduced a regression of sorts in the g++.dg/pr53037-4.C test on ia64.
https://gcc.gnu.org/ml/gcc-testresults/2017-12/msg00672.html The regression hasn't been noticed anywhere else only because all the other targets apparently have no low limit on function alignment, whereas ia64 has a limit of 32. As a result of the limit the i64 compiler would issue not one but two errors for a function declaration with attribute warn_if_not_aligned that specifies a value less than 32: one for the attribute itself (because it's not allowed on functions), and another for the lower value. The attached patch fixes this by issuing the error only for attribute aligned with a lower requirement but not attribute warn_if_not_aligned. I tried to come up with a test for this that would fail on other targets besides ia64 (those with no low bound on function alignment) but couldn't find a way to do it. If someone knows of a way I'd be glad to add a better test than pr53037-4.C. Martin
gcc/c-family/ChangeLog: * c-attribs.c (common_handle_aligned_attribute): Avoid issuing an error for attribute warn_if_not_aligned. diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 186df05..74c971d 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -1886,14 +1886,17 @@ common_handle_aligned_attribute (tree *node, tree name, tree args, int flags, curalign /= BITS_PER_UNIT; bitalign /= BITS_PER_UNIT; + bool diagd = true; if (DECL_USER_ALIGN (decl) || DECL_USER_ALIGN (last_decl)) - warning (OPT_Wattributes, - "ignoring attribute %<%E (%u)%> because it conflicts with " - "attribute %<%E (%u)%>", name, bitalign, name, curalign); - else + diagd = warning (OPT_Wattributes, + "ignoring attribute %<%E (%u)%> because it conflicts " + "with attribute %<%E (%u)%>", + name, bitalign, name, curalign); + else if (!warn_if_not_aligned_p) + /* Do not error out for attribute warn_if_not_aligned. */ error ("alignment for %q+D must be at least %d", decl, curalign); - if (note) + if (diagd && note) inform (DECL_SOURCE_LOCATION (last_decl), "previous declaration here"); *no_add_attrs = true;