gcc and edg accept: namespace mozilla { struct Proxy; } using mozilla::Proxy; struct Proxy { }; Proxy mProxy; clang rejects: error: reference to 'Proxy' is ambiguous That code looks really strange, but both gcc and edg accept it.
I tested a variation: namespace mozilla { struct Proxy; } struct Proxy { }; using mozilla::Proxy; Proxy mProxy; and both gcc and edg refuse to accept mProxy complaining about a definition with incomplete type.
one "last" test both gcc and edg accept. It shows that they are merging the declaration and definition: namespace mozilla { struct Proxy; } using mozilla::Proxy; struct Proxy { int a; }; mozilla::Proxy mProxy; int f() { return mProxy.a; }
The relevant bit of code (in SemaDecl.cpp): if (TagDecl *PrevTagDecl = dyn_cast<TagDecl>(PrevDecl)) { // If this is a use of a previous tag, or if the tag is already declared // in the same scope (so that the definition/declaration completes or // rementions the tag), reuse the decl. if (TUK == TUK_Reference || TUK == TUK_Friend || isDeclInScope(PrevDecl, SearchDC, S, isExplicitSpecialization)) { This code makes us not treat the second declaration of Proxy as a redeclaration even though lookup finds the previous declaration. Not sure what the right predicate is.
another testcase: /* g++ accepts this but clang dignoses: error3.cpp:18:5: error: call to 'f' is ambiguous */ namespace A { extern "C" int f(int i = 5) { return i + 2; } } namespace B { extern "C" int f(int i = 5); } using A::f; using B::f; int main(void) { /* extern "C" should conceptually nullify overloading * so why does clang consider this function ambiguous? */ f(3); }