From: Reid Kleckner Date: Tue, 25 Mar 2014 20:31:28 +0000 (+0000) Subject: -fms-compatibility: Only form implicit member exprs for unqualified ids X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c5ba03d8a7d2febc14d4f3830c7f2b0e2fec7341;p=clang -fms-compatibility: Only form implicit member exprs for unqualified ids If there are any scope specifiers, then a base class must be named or the symbol isn't from a base class. Fixes PR19233. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204753 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 80220c0d14..f0e0485e23 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2044,17 +2044,17 @@ ExprResult Sema::ActOnIdExpression(Scope *S, if (R.empty()) { // In Microsoft mode, if we are inside a template class member function // whose parent class has dependent base classes, and we can't resolve - // an identifier, then assume the identifier is a member of a dependent - // base class. The goal is to postpone name lookup to instantiation time - // to be able to search into the type dependent base classes. + // an unqualified identifier, then assume the identifier is a member of a + // dependent base class. The goal is to postpone name lookup to + // instantiation time to be able to search into the type dependent base + // classes. // FIXME: If we want 100% compatibility with MSVC, we will have delay all // unqualified name lookup. Any name lookup during template parsing means // clang might find something that MSVC doesn't. For now, we only handle // the common case of members of a dependent base class. - if (getLangOpts().MSVCCompat) { + if (SS.isEmpty() && getLangOpts().MSVCCompat) { CXXMethodDecl *MD = dyn_cast(CurContext); if (MD && MD->isInstance() && MD->getParent()->hasAnyDependentBases()) { - assert(SS.isEmpty() && "qualifiers should be already handled"); QualType ThisType = MD->getThisType(Context); // Since the 'this' expression is synthesized, we don't need to // perform the double-lookup check. diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp index e956cd11c5..8f9653da05 100644 --- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp +++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp @@ -236,3 +236,26 @@ template struct D : T { template struct D; } + +namespace PR19233 { +template +struct A : T { + void foo() { + ::undef(); // expected-error {{no member named 'undef' in the global namespace}} + } + void bar() { + ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}} + } + void baz() { + B::qux(); // expected-error {{use of undeclared identifier 'B'}} + } +}; + +struct B { void qux(); }; +struct C : B { }; +template struct A; // No error! B is a base of A, and qux is available. + +struct D { }; +template struct A; // expected-note {{in instantiation of member function 'PR19233::A::baz' requested here}} + +}