Hi! For -Wredundant-tags or -Wmismatched-tags, cp_parser_maybe_warn_enum_key and cp_parser_check_class_key perform an extra name lookup to check if the enum/struct/class/union keyword is redundant, but as the testcase shows, if it is not redundant, but there is e.g. a hidden member with the same name, it results in bogus error about accessing the member, although that should be diagnosed only if the non-redundant keyword is not present.
So, I think we need to ensure the lookup doesn't perform nor queue any access checks. Furthermore, I don't see the point in performing the lookup for enums if the warning is disabled (by default), for struct/class/union we already don't perform it if both warnings are disabled. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2020-01-04 Jakub Jelinek <ja...@redhat.com> PR c++/93138 * parser.c (cp_parser_check_class_key): Disable access checks for the simple name lookup. (cp_parser_maybe_warn_enum_key): Likewise. Return early if !warn_redundant_tags. * g++.dg/warn/Wredundant-tags-2.C: New test. --- gcc/cp/parser.c.jj 2020-01-01 12:22:34.078474448 +0100 +++ gcc/cp/parser.c 2020-01-03 10:56:53.899072533 +0100 @@ -30663,11 +30663,15 @@ static void cp_parser_maybe_warn_enum_key (cp_parser *parser, location_t key_loc, tree type, rid scoped_key) { + if (!warn_redundant_tags) + return; + tree type_decl = TYPE_MAIN_DECL (type); tree name = DECL_NAME (type_decl); - /* Look up the NAME to see if it unambiguously refers to the TYPE - and set KEY_REDUNDANT if so. */ + /* Look up the NAME to see if it unambiguously refers to the TYPE. */ + push_deferring_access_checks (dk_no_check); tree decl = cp_parser_lookup_name_simple (parser, name, input_location); + pop_deferring_access_checks (); /* The enum-key is redundant for uses of the TYPE that are not declarations and for which name lookup returns just the type @@ -30837,7 +30841,9 @@ cp_parser_check_class_key (cp_parser *pa tree name = DECL_NAME (type_decl); /* Look up the NAME to see if it unambiguously refers to the TYPE and set KEY_REDUNDANT if so. */ + push_deferring_access_checks (dk_no_check); tree decl = cp_parser_lookup_name_simple (parser, name, input_location); + pop_deferring_access_checks (); /* The class-key is redundant for uses of the CLASS_TYPE that are neither definitions of it nor declarations, and for which name --- gcc/testsuite/g++.dg/warn/Wredundant-tags-2.C.jj 2020-01-03 10:56:10.408730751 +0100 +++ gcc/testsuite/g++.dg/warn/Wredundant-tags-2.C 2020-01-03 10:56:00.525880326 +0100 @@ -0,0 +1,18 @@ +// PR c++/93138 +// { dg-do compile } +// { dg-options "-Wredundant-tags" } + +struct Foo +{ + enum Kind { a }; +private: + Kind Kind; +}; +enum Foo::Kind foo (); // { dg-bogus "is private within this context|redundant" } +struct Bar +{ + struct Kind { int a; }; +private: + Kind Kind; +}; +struct Bar::Kind bar (); // { dg-bogus "is private within this context|redundant" } Jakub