It seems wrong to issue a -Wignored-qualifiers warning for code like: static_assert(!is_same_v<void(*)(), const void(*)()>);
because there the qualifier matters. Likewise in template specialization: template<typename T> struct S { }; template<> struct S<void(*)()> { }; template<> struct S<const void(*)()> { }; // OK, not a redefinition I'm of the mind that we should disable the warning for template arguments, as in the patch below. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? PR c++/107492 gcc/cp/ChangeLog: * parser.cc (cp_parser_template_type_arg): Suppress -Wignored-qualifiers warning. gcc/testsuite/ChangeLog: * g++.dg/warn/Wignored-qualifiers3.C: New test. --- gcc/cp/parser.cc | 4 ++++ gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C | 12 ++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index e0e3cf3eaf6..54ad4b98ed3 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -24334,6 +24334,10 @@ cp_parser_template_type_arg (cp_parser *parser) const char *saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message = G_("types may not be defined in template arguments"); + /* It's wrong to issue a -Wignored-qualifiers warning for + static_assert(!is_same_v<void(*)(), const void(*)()>); + because there the qualifier matters. */ + warning_sentinel w (warn_ignored_qualifiers); r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE, true, false, NULL); parser->type_definition_forbidden_message = saved_message; if (cxx_dialect >= cxx14 && !flag_concepts && type_uses_auto (r)) diff --git a/gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C b/gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C new file mode 100644 index 00000000000..5696feaaefe --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C @@ -0,0 +1,12 @@ +// PR c++/107492 +// { dg-do compile { target c++14 } } +// { dg-additional-options "-Wignored-qualifiers" } + +template<typename T> struct S { }; +template<> struct S<void(*)()> { }; +template<> struct S<const void(*)()> { }; // { dg-bogus "ignored" } + +template<typename T, typename U> constexpr bool is_same_v = false; +template<typename T> constexpr bool is_same_v<T, T> = true; + +static_assert( ! is_same_v< void(*)(), const void(*)() >, ""); // { dg-bogus "ignored" } base-commit: e7310e24b1c0ca67b1bb507c1330b2bf39e59e32 -- 2.38.1