c++: Fix injected-class-name lookup with multiple bases [PR122509]

When looking up an unqualified injected-class-name in a member access
expression (e.g., D().v<int>), cp_parser_lookup_name calls lookup_member
with protect=0, causing it to return NULL on ambiguity instead of the
candidate list. This prevented the existing DR 176 logic in
maybe_get_template_decl_from_type_decl from resolving the ambiguity.

Per DR 176, if all ambiguous candidates are instantiations of the same
class template and the name is followed by a template-argument-list,
the reference is to the template itself and is not ambiguous.

Fix by using protect=2 to return the ambiguous candidate list.

	PR c++/122509

gcc/cp/ChangeLog:

	* parser.cc (cp_parser_lookup_name): Use protect=2 instead of
	protect=0 when calling lookup_member.

gcc/testsuite/ChangeLog:

	* g++.dg/tc1/dr176-2.C: New test.

Signed-off-by: Egas Ribeiro <egas.g.ribeiro@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
This commit is contained in:
Egas Ribeiro
2025-12-13 20:06:09 +00:00
committed by Jason Merrill
parent 7044071f07
commit d19b95ca96
2 changed files with 14 additions and 1 deletions

View File

@@ -34241,7 +34241,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
parse, those errors are valid. */
decl = lookup_member (object_type,
name,
/*protect=*/0,
/*protect=*/2,
/*prefer_type=*/tag_type != none_type,
tf_warning_or_error);
else

View File

@@ -0,0 +1,13 @@
// { dg-do compile }
// PR c++/122509
namespace s {
template<class A>
struct v {
void size() {}
};
}
struct D : public s::v<double>, public s::v<int> {};
int main() {
D().v<int>::size();
}