diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-03-25 20:31:28 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-03-25 20:31:28 +0000 |
commit | 83055ade751b4c3528e07a75b510d96bf9efe4d4 (patch) | |
tree | a760ff9409dd08733a6c32061842e20139d75632 | |
parent | c3826b5ba6a434a1783c4e5b02a9ea2750589177 (diff) | |
download | bcm5719-llvm-83055ade751b4c3528e07a75b510d96bf9efe4d4.tar.gz bcm5719-llvm-83055ade751b4c3528e07a75b510d96bf9efe4d4.zip |
-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.
llvm-svn: 204753
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 10 | ||||
-rw-r--r-- | clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp | 23 |
2 files changed, 28 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 80220c0d14b..f0e0485e231 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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<CXXMethodDecl>(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/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp index e956cd11c54..8f9653da05e 100644 --- a/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp +++ b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp @@ -236,3 +236,26 @@ template <typename T> struct D : T { template struct D<A>; } + +namespace PR19233 { +template <class T> +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<C>; // No error! B is a base of A<C>, and qux is available. + +struct D { }; +template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}} + +} |