In following code foo::tag and bar::tag are type aliases to the same type so member name lookup in foobar::tag should merge them and not be ambiguous. However GCC 15.0.0 20240604 gives error about ambiguity. ```https://godbolt.org/z/fsK7ET4bY struct tag { }; struct foo { using tag = tag; }; struct bar { using tag = tag; }; struct foobar : foo, bar { }; int main() { foobar::tag _; } ``` Clang is able to compile the code and it would make sense to no be ambiguous but I'm not 100% sure, so someone with more familiarity with [class.member.lookup] section of the standard can correct me if I'm wrong.
Note the original example is invalid code to begin. ``` <source>:5:11: warning: declaration of 'using foo::tag = struct tag' changes meaning of 'tag' [-Wchanges-meaning] 5 | using tag = tag; | ^~~ <source>:5:17: note: used here to mean 'struct tag' 5 | using tag = tag; | ^~~ <source>:2:8: note: declared here 2 | struct tag { }; | ^~~ ``` But a simple change to the source: ``` struct tag { }; struct foo { using tag1 = tag; }; struct bar { using tag1 = tag; }; struct foobar : foo, bar { }; int main() { foobar::tag1 _; } ``` Gets the questionable ambiguous error message without a warning.
MSVC rejects the code: <source>(15): error C2385: ambiguous access of 'tag1' <source>(15): note: could be the 'tag1' in base 'foo' <source>(15): note: or could be the 'tag1' in base 'bar' So does EDG: "<source>", line 15: error: "foobar::tag1" is ambiguous foobar::tag1 _; ^ 1 error detected in the compilation of "<source>". Which makes this me 99% sure this is a clang issue.