summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaTemplate
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaTemplate')
-rw-r--r--clang/test/SemaTemplate/ms-delayed-default-template-args.cpp9
-rw-r--r--clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp32
2 files changed, 40 insertions, 1 deletions
diff --git a/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp b/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp
index ca9ddb0d9d1..0c054694247 100644
--- a/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp
+++ b/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp
@@ -55,6 +55,15 @@ struct Foo {
typedef int Weber;
}
+// MSVC accepts this, but Clang doesn't.
+namespace test_scope_spec {
+template <typename T = ns::Bar> // expected-error {{use of undeclared identifier 'ns'}}
+struct Foo {
+ static_assert(sizeof(T) == 4, "Bar should have gotten int");
+};
+namespace ns { typedef int Bar; }
+}
+
#ifdef __clang__
// These are negative test cases that MSVC doesn't compile either. Try to use
// unique undeclared identifiers so typo correction doesn't find types declared
diff --git a/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
index 4f3df277d91..51d19cef382 100644
--- a/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
template <class T>
@@ -573,3 +573,33 @@ void h();
template <typename T> decltype(h(T())) check2(); // expected-note{{candidate template ignored: substitution failure [with T = int]: no matching function for call to 'h'}}
decltype(check2<int>()) y; // expected-error{{no matching function for call to 'check2'}}
}
+
+// We also allow unqualified lookup into bases in contexts where the we know the
+// undeclared identifier *must* be a type, such as a new expression or catch
+// parameter type.
+template <typename T>
+struct UseUnqualifiedTypeNames : T {
+ void foo() {
+ void *P = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}
+ size_t x = __builtin_offsetof(TheType, f2); // expected-warning {{unqualified lookup}} expected-error {{no type}}
+ try {
+ } catch (TheType) { // expected-warning {{unqualified lookup}} expected-error {{no type}}
+ }
+ enum E : IntegerType { E0 = 42 }; // expected-warning {{unqualified lookup}} expected-error {{no type}}
+ _Atomic(TheType) a; // expected-warning {{unqualified lookup}} expected-error {{no type}}
+ }
+ void out_of_line();
+};
+template <typename T>
+void UseUnqualifiedTypeNames<T>::out_of_line() {
+ void *p = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}
+}
+struct Base {
+ typedef int IntegerType;
+ struct TheType {
+ int f1, f2;
+ };
+};
+template struct UseUnqualifiedTypeNames<Base>;
+struct BadBase { };
+template struct UseUnqualifiedTypeNames<BadBase>; // expected-note-re 2 {{in instantiation {{.*}} requested here}}
OpenPOWER on IntegriCloud