https://gcc.gnu.org/g:d19b95ca96f2e10732007d9cd59e6430df8d0b2a
commit r16-6274-gd19b95ca96f2e10732007d9cd59e6430df8d0b2a Author: Egas Ribeiro <[email protected]> Date: Sat Dec 13 20:06:09 2025 +0000 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 <[email protected]> Reviewed-by: Jason Merrill <[email protected]> Diff: --- gcc/cp/parser.cc | 2 +- gcc/testsuite/g++.dg/tc1/dr176-2.C | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 4685a9ab80fa..89d2b9e692f2 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -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 diff --git a/gcc/testsuite/g++.dg/tc1/dr176-2.C b/gcc/testsuite/g++.dg/tc1/dr176-2.C new file mode 100644 index 000000000000..b639aaf0c161 --- /dev/null +++ b/gcc/testsuite/g++.dg/tc1/dr176-2.C @@ -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(); +}
