The -Wredundant-tags warning, new in GCC 10, issues false positives for some declarations involving typename. Typename isn't a C++ class-key so the warning is not intended in these cases. Attached is a simple fix tested on x86_64-linux.
Martin
PR c++/93801 - False -Wmismatched-tags upon redundant typename gcc/cp/ChangeLog: PR c++/93801 * parser.c (cp_parser_check_class_key): Only handle true C++ class-keys. gcc/testsuite/ChangeLog: PR c++/93801 * g++.dg/warn/Wredundant-tags-3.C: New test. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e8a536ae22f..03946b6d7b1 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -30995,6 +30995,13 @@ cp_parser_check_class_key (cp_parser *parser, location_t key_loc, tree decl = cp_parser_lookup_name_simple (parser, name, input_location); pop_deferring_access_checks (); + /* Only consider the true class-keys below and ignore typename_type, + etc. that are not C++ class-keys. */ + if (class_key != class_type + && class_key != record_type + && class_key != union_type) + return; + /* The class-key is redundant for uses of the CLASS_TYPE that are neither definitions of it nor declarations, and for which name lookup returns just the type itself. */ diff --git a/gcc/testsuite/g++.dg/warn/Wredundant-tags-3.C b/gcc/testsuite/g++.dg/warn/Wredundant-tags-3.C new file mode 100644 index 00000000000..7b30e949d0c --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wredundant-tags-3.C @@ -0,0 +1,45 @@ +/* PR c++/93801 - False -Wmismatched-tags upon redundant typename + { dg-do compile } + { dg-options "-Wall -Wredundant-tags" } */ + +namespace N +{ + class C { }; + enum E { }; + struct S { }; + union U { }; + + template <int> class TC { }; + template <int> struct TS { }; + template <int> union TU { }; +} + +N::C c1; +typename N::C c2; // { dg-bogus "-Wredundant-tags" } +class N::C c3; // { dg-warning "-Wredundant-tags" } + +N::E e1; +typename N::E e2; // { dg-bogus "-Wredundant-tags" } +enum N::E e3; // { dg-warning "-Wredundant-tags" } + +N::S s1; +typename N::S s2; // { dg-bogus "-Wredundant-tags" } +struct N::S s3; // { dg-warning "-Wredundant-tags" } + +N::U u1; +typename N::U u2; // { dg-bogus "-Wredundant-tags" } + // { dg-bogus "'class' tag used in naming 'union N::U" "pr93809" { xfail *-*-*} .-1 } +union N::U u3; // { dg-warning "-Wredundant-tags" } + + +typedef N::TC<0> TC0; +typedef typename N::TC<0> TC0; +typedef class N::TC<0> TC0; // { dg-warning "-Wredundant-tags" "pr93809" { xfail *-*-*} .-1 } + +typedef N::TS<0> TS0; +typedef typename N::TS<0> TS0; +typedef struct N::TS<0> TS0; // { dg-warning "-Wredundant-tags" "pr93809" { xfail *-*-*} .-1 } + +typedef N::TS<0> TS0; +typedef typename N::TS<0> TS0; +typedef struct N::TS<0> TS0; // { dg-warning "-Wredundant-tags" "pr93809" { xfail *-*-*} .-1 }