Hello, Martin, The initial patch for PR 81824 fixed one of the possibilities of -Wmissing-attributes reporting duplicates, namely, if TMPL had an attribute in ATTRLIST that was missing from DECL's decl and type attribute lists, both being non-empty.
Another possibility of duplicate reporting remained: when an attribute in ATTRLIST is present in both decl and type attribute lists of TMPL, and absent from DECL's attribute lists, it is reported once for each of TMPL's lists. The implementation still allowed for false positives: an attribute in ATTRLIST that is present in TMPL will be regarded as missing as soon as it is not found in DECL's decl attribute list, even if it is later found in DECL's type attribute list. This patch fixes both problems, so that an attribute from ATTRLIST that is present in any of TMPL's lists will be reported at most once, and only if it is missing from both DECL's lists. Now, I realize there are some attributes that are only acceptable for types, and some that are only acceptable for function declarations. ISTM that some even have different meanings depending on whether they're associated with types or declarations. There's room for an argument for checking only corresponding lists, for at least some of the attributes. AFAICT it doesn't apply to -Wmissing-attributes, that are either acceptable in either list, or only in the FUNCTION_DECL list, so I'm leaving it at that in the hope that it doesn't apply to any other users of decls_mismatched_attributes either. Regstrapping on x86_64-linux-gnu. Ok to install if it passes? for gcc/ChangeLog PR middle-end/81824 * attribs.c (decls_mismatched_attributes): Avoid duplicates and false positives. for gcc/testsuite/ChangeLog PR middle-end/81824 * g++.dg/Wmissing-attributes-1.C: New. --- gcc/attribs.c | 14 +++++-- gcc/testsuite/g++.dg/Wmissing-attributes-1.C | 55 ++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/Wmissing-attributes-1.C diff --git a/gcc/attribs.c b/gcc/attribs.c index 8e5401655972..f4777c6a8233 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -1931,15 +1931,19 @@ decls_mismatched_attributes (tree tmpl, tree decl, tree attrlist, if (!has_attribute (tmpls[j], tmpl_attrs[j], blacklist[i])) continue; + bool found = false; unsigned kmax = 1 + !!decl_attrs[1]; for (unsigned k = 0; k != kmax; ++k) { if (has_attribute (decls[k], decl_attrs[k], blacklist[i])) - break; - - if (!k && kmax > 1) - continue; + { + found = true; + break; + } + } + if (!found) + { if (nattrs) pp_string (attrstr, ", "); pp_begin_quote (attrstr, pp_show_color (global_dc->printer)); @@ -1947,6 +1951,8 @@ decls_mismatched_attributes (tree tmpl, tree decl, tree attrlist, pp_end_quote (attrstr, pp_show_color (global_dc->printer)); ++nattrs; } + + break; } } diff --git a/gcc/testsuite/g++.dg/Wmissing-attributes-1.C b/gcc/testsuite/g++.dg/Wmissing-attributes-1.C new file mode 100644 index 000000000000..56d28b339e17 --- /dev/null +++ b/gcc/testsuite/g++.dg/Wmissing-attributes-1.C @@ -0,0 +1,55 @@ +// { dg-do compile } +// { dg-options "-Wmissing-attributes" } + +#define ATTR(list) __attribute__ (list) + +/* Type attributes are normally absent in template functions, and the + mere presence of any such attribute used to cause the + -Wmissing-attributes checks, that checked for attributes typically + associated with functions rather than types, to report any missing + attributes twice: once for the specialization attribute list, once + for its type attribute list. + + If we force any of the checked-for attributes to be associated with + types rather than functions, even later implementations that fixed + the duplicate reporting problem above would still report them as + missing (in the function attribute list) even when present (in the + type attribute list). */ +typedef void* ATTR ((alloc_size (1))) f_type (int); + +template <class T> +f_type +ATTR ((malloc)) +missing_malloc; // { dg-message "missing primary template attribute .malloc." } + +template <> +f_type +missing_malloc<char>; // { dg-warning "explicit specialization .\[^\n\r\]+. may be missing attributes" } + + +/* Check that even an attribute that appears in both lists (decl and + type) in a template declaration is reported as missing only + once. */ + +template <class T> +f_type +ATTR ((alloc_size (1))) // In both attr lists, decl's and type's. +missing_alloc_size; // { dg-message "missing primary template attribute .alloc_size." } + +template <> +void * +missing_alloc_size<char>(int); // { dg-warning "explicit specialization .\[^\n\r\]+. may be missing attributes" } + + +/* Check that even an attribute that appears in both lists (decl and + type) is not report as missing if it's present only in the type + list. */ + +template <class T> +f_type +ATTR ((alloc_size (1))) // In both attr lists, decl's and type's. +missing_nothing; + +template <> +f_type +missing_nothing<char>; -- Alexandre Oliva, freedom fighter he/him https://FSFLA.org/blogs/lxo Be the change, be Free! FSF Latin America board member GNU Toolchain Engineer Free Software Evangelist Hay que enGNUrecerse, pero sin perder la terGNUra jamás - Che GNUevara