summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaCXXScopeSpec.cpp9
-rw-r--r--clang/test/SemaTemplate/lookup-dependent-bases.cpp63
-rw-r--r--clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp14
3 files changed, 68 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index a70aca2ad86..b1b8b5d1dc9 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -703,8 +703,13 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
if (getLangOpts().MSVCCompat) {
DeclContext *DC = LookupCtx ? LookupCtx : CurContext;
if (DC->isDependentContext() && DC->isFunctionOrMethod()) {
- SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc);
- return false;
+ CXXRecordDecl *ContainingClass = dyn_cast<CXXRecordDecl>(DC->getParent());
+ if (ContainingClass && ContainingClass->hasAnyDependentBases()) {
+ Diag(IdentifierLoc, diag::ext_undeclared_unqual_id_with_dependent_base)
+ << &Identifier << ContainingClass;
+ SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc);
+ return false;
+ }
}
}
diff --git a/clang/test/SemaTemplate/lookup-dependent-bases.cpp b/clang/test/SemaTemplate/lookup-dependent-bases.cpp
index 61fca4a2a45..f7867d8339b 100644
--- a/clang/test/SemaTemplate/lookup-dependent-bases.cpp
+++ b/clang/test/SemaTemplate/lookup-dependent-bases.cpp
@@ -1,20 +1,55 @@
// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
-// expected-no-diagnostics
-class C {
-public:
- static void foo2() { }
+namespace basic {
+struct C {
+ static void foo2() {}
};
-template <class T>
-class A {
-public:
- typedef C D;
+template <typename T>
+struct A {
+ typedef C D;
};
-template <class T>
-class B : public A<T> {
-public:
- void foo() {
- D::foo2();
- }
+template <typename T>
+struct B : A<T> {
+ void foo() {
+ D::foo2(); // expected-warning {{use of undeclared identifier 'D'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}}
+ }
};
+
+template struct B<int>; // Instantiation has no warnings.
+}
+
+namespace nested_nodep_base {
+// There are limits to our hacks, MSVC accepts this, but we don't.
+struct A {
+ struct D { static void foo2(); };
+};
+template <typename T>
+struct B : T {
+ struct C {
+ void foo() {
+ D::foo2(); // expected-error {{use of undeclared identifier 'D'}}
+ }
+ };
+};
+
+template struct B<A>; // Instantiation has no warnings.
+}
+
+namespace nested_dep_base {
+// We actually accept this because the inner class has a dependent base even
+// though it isn't a template.
+struct A {
+ struct D { static void foo2(); };
+};
+template <typename T>
+struct B {
+ struct C : T {
+ void foo() {
+ D::foo2(); // expected-warning {{use of undeclared identifier 'D'; unqualified lookup into dependent bases of class template 'C' is a Microsoft extension}}
+ }
+ };
+};
+
+template struct B<A>; // Instantiation has no warnings.
+}
diff --git a/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
index 40f73c0d9e6..4bdb97bbbd1 100644
--- a/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -220,7 +220,8 @@ template <typename T> struct C : T {
int *bar() { return &b; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
int baz() { return T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}}
int T::*qux() { return &T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}}
- int T::*fuz() { return &U::a; } // expected-error {{use of undeclared identifier 'U'}}
+ int T::*fuz() { return &U::a; } // expected-error {{use of undeclared identifier 'U'}} \
+ // expected-warning {{unqualified lookup into dependent bases of class template 'C'}}
};
template struct B<A>;
@@ -249,7 +250,8 @@ struct A : T {
::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}}
}
void baz() {
- B::qux(); // expected-error {{use of undeclared identifier 'B'}}
+ B::qux(); // expected-error {{use of undeclared identifier 'B'}} \
+ // expected-warning {{unqualified lookup into dependent bases of class template 'A'}}
}
};
@@ -460,3 +462,11 @@ template <typename T> struct D : C<T> {
int x = f<NameFromBase>();
};
}
+
+namespace function_template_undef_impl {
+template<class T>
+void f() {
+ Undef::staticMethod(); // expected-error {{use of undeclared identifier 'Undef'}}
+ UndefVar.method(); // expected-error {{use of undeclared identifier 'UndefVar'}}
+}
+}
OpenPOWER on IntegriCloud