https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124186
Bug ID: 124186
Summary: lookup ambiguity by using declarations
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: aoliva at gcc dot gnu.org
Target Milestone: ---
struct VB { int i; };
struct B1 : virtual VB { using VB::i; };
struct B2 : virtual VB { using VB::i; };
struct B3 : virtual VB { };
struct B4 : VB { using VB::i; };
struct D14 : B1, B4 { void inc() { i++; } };
struct D23 : B2, B3 { void inc() { i++; } };
struct D34 : B3, B4 { void inc() { i++; } };
int B3::*p = &D34::i;
struct D12 : B1, B2 { void inc() { i++; } };
D14::inc is correctly rejected because the using declarations in B1 and B4
refer to distinct VB-typed subobjects: lookup is not ambiguous, but the member
reference is.
D23::inc correctly compiles, because the using declaration in B2 overrides that
in VB in both inheritance paths.
D34::inc is rejected, correctly AFAICT, but lookup should not be ambiguous, the
member reference is. (int B3::*p = &D34::i; // Unambiguous per
[class.member.lookup]/11, but we reject it)
D12::inc should compile but doesn't, because we find using declarations in both
B1 and B2, and consider the lookup ambiguous instead of realizing they both
refer to the same member of the same subobject.
ISTM that our lookup_member logic, that combines lookup and reference ambiguity
checks, hasn't been updated since the introduction, in C++11, of the new
description of the member lookup algorithm, but perhaps the underlying
algorithm is meant to be equivalent, since I've seen arguments that D12::inc
should compile even in C++03.
Ideally, when reporting ambiguity, we should report inheritance paths that make
the distinct sub-objects clear; reporting VB::i vs VB::i as ambiguous could be
improved by distinguishing between e.g. B1::VB::i and B4::VB::i.