summaryrefslogtreecommitdiff
path: root/test/SemaTemplate
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r--test/SemaTemplate/anonymous-union.cpp4
-rw-r--r--test/SemaTemplate/class-template-decl.cpp6
-rw-r--r--test/SemaTemplate/deduction.cpp5
-rw-r--r--test/SemaTemplate/dependent-names.cpp5
-rw-r--r--test/SemaTemplate/dependent-type-identity.cpp4
-rw-r--r--test/SemaTemplate/destructor-template.cpp10
-rw-r--r--test/SemaTemplate/explicit-specialization-member.cpp2
-rw-r--r--test/SemaTemplate/ext_ms_template_spec.cpp33
-rw-r--r--test/SemaTemplate/friend.cpp16
-rw-r--r--test/SemaTemplate/instantiate-local-class.cpp200
-rw-r--r--test/SemaTemplate/instantiate-non-dependent-types.cpp2
-rw-r--r--test/SemaTemplate/instantiate-static-var.cpp12
-rw-r--r--test/SemaTemplate/ms-lookup-template-base-classes.cpp69
-rw-r--r--test/SemaTemplate/virtual-member-functions.cpp4
14 files changed, 356 insertions, 16 deletions
diff --git a/test/SemaTemplate/anonymous-union.cpp b/test/SemaTemplate/anonymous-union.cpp
index 97ecd6e60cca..75d53aa5345f 100644
--- a/test/SemaTemplate/anonymous-union.cpp
+++ b/test/SemaTemplate/anonymous-union.cpp
@@ -8,7 +8,7 @@ struct T0 {
};
};
template <typename T>
-struct T1 : public T0, public T {
+struct T1 : public T0, public T { //expected-warning{{direct base 'T0' is inaccessible due to ambiguity:\n struct T1<struct A> -> struct T0\n struct T1<struct A> -> struct A -> struct T0}}
void f0() {
m0 = 0; // expected-error{{ambiguous conversion}}
}
@@ -16,7 +16,7 @@ struct T1 : public T0, public T {
struct A : public T0 { };
-void f1(T1<A> *S) { S->f0(); } // expected-note{{instantiation of member function}}
+void f1(T1<A> *S) { S->f0(); } // expected-note{{instantiation of member function}} expected-note{{in instantiation of template class 'T1<A>' requested here}}
namespace rdar8635664 {
template<typename T>
diff --git a/test/SemaTemplate/class-template-decl.cpp b/test/SemaTemplate/class-template-decl.cpp
index c67361bfeafb..4f861dea7058 100644
--- a/test/SemaTemplate/class-template-decl.cpp
+++ b/test/SemaTemplate/class-template-decl.cpp
@@ -146,3 +146,9 @@ namespace redecl {
};
};
}
+
+extern "C" template <typename T> // expected-error{{templates must have C++ linkage}}
+void DontCrashOnThis() {
+ T &pT = T();
+ pT;
+}
diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp
index c59f10dbb12e..e33d1576da58 100644
--- a/test/SemaTemplate/deduction.cpp
+++ b/test/SemaTemplate/deduction.cpp
@@ -202,3 +202,8 @@ namespace PR19372 {
using T = S<int, int>;
}
}
+
+namespace PR18645 {
+ template<typename F> F Quux(F &&f);
+ auto Baz = Quux(Quux<float>);
+}
diff --git a/test/SemaTemplate/dependent-names.cpp b/test/SemaTemplate/dependent-names.cpp
index 011e073a727a..d5c9d66c4526 100644
--- a/test/SemaTemplate/dependent-names.cpp
+++ b/test/SemaTemplate/dependent-names.cpp
@@ -414,3 +414,8 @@ namespace PR19936 {
template<typename T> decltype(*T()) f() {} // expected-error {{redefinition}}
template<typename T> decltype(T() * T()) g() {} // expected-error {{redefinition}}
}
+
+template <typename> struct CT2 {
+ template <class U> struct X;
+};
+template <typename T> int CT2<int>::X<>; // expected-error {{template parameter list matching the non-templated nested type 'CT2<int>' should be empty}}
diff --git a/test/SemaTemplate/dependent-type-identity.cpp b/test/SemaTemplate/dependent-type-identity.cpp
index 5b9da5d89258..6b23a38f8486 100644
--- a/test/SemaTemplate/dependent-type-identity.cpp
+++ b/test/SemaTemplate/dependent-type-identity.cpp
@@ -111,7 +111,9 @@ namespace PR18275 {
void A<T>::f(int x) { x = 0; }
template<typename T>
- void A<T>::g(const int x) { x = 0; } // expected-error {{not assignable}}
+ void A<T>::g(const int x) { // expected-note {{declared const here}}
+ x = 0; // expected-error {{cannot assign to variable 'x'}}
+ }
template<typename T>
void A<T>::h(T) {} // FIXME: Should reject this. Type is different from prior decl if T is an array type.
diff --git a/test/SemaTemplate/destructor-template.cpp b/test/SemaTemplate/destructor-template.cpp
index 4e1af9ad1f96..853ba492f8e7 100644
--- a/test/SemaTemplate/destructor-template.cpp
+++ b/test/SemaTemplate/destructor-template.cpp
@@ -52,9 +52,13 @@ namespace PR7239 {
}
namespace PR7904 {
- struct Foo {
- template <int i> ~Foo() {} // expected-error{{destructor cannot be declared as a template}}
- };
+ struct Foo {};
+ template <class T>
+ Foo::~Foo() { // expected-error{{destructor cannot be declared as a template}}
+ T t;
+ T &pT = t;
+ pT;
+ }
Foo f;
}
diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp
index e8dc4d219acb..f302836c7e4b 100644
--- a/test/SemaTemplate/explicit-specialization-member.cpp
+++ b/test/SemaTemplate/explicit-specialization-member.cpp
@@ -17,7 +17,7 @@ namespace PR6161 {
{
static locale::id id; // expected-error{{use of undeclared identifier}}
};
- numpunct<char>::~numpunct(); // expected-error{{expected the class name after '~' to name a destructor}}
+ numpunct<char>::~numpunct();
}
namespace PR12331 {
diff --git a/test/SemaTemplate/ext_ms_template_spec.cpp b/test/SemaTemplate/ext_ms_template_spec.cpp
new file mode 100644
index 000000000000..fc2ed16f9f8a
--- /dev/null
+++ b/test/SemaTemplate/ext_ms_template_spec.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -fms-extensions -std=c++11 -verify %s
+
+namespace A {
+
+template <class T>
+class ClassTemplate; // expected-note {{explicitly specialized declaration is here}}
+
+template <class T1, class T2>
+class ClassTemplatePartial; // expected-note {{explicitly specialized declaration is here}}
+
+template <typename T> struct X {
+ struct MemberClass; // expected-note {{explicitly specialized declaration is here}}
+ enum MemberEnumeration; // expected-note {{explicitly specialized declaration is here}} // expected-error {{ISO C++ forbids forward references to 'enum' types}}
+};
+
+}
+
+namespace B {
+
+template <>
+class A::ClassTemplate<int>; // expected-warning {{class template specialization of 'ClassTemplate' outside namespace enclosing 'A' is a Microsoft extension}}
+
+template <class T1>
+class A::ClassTemplatePartial<T1, T1 *> {}; // expected-warning {{class template partial specialization of 'ClassTemplatePartial' outside namespace enclosing 'A' is a Microsoft extension}}
+
+template <>
+struct A::X<int>::MemberClass; // expected-warning {{member class specialization of 'MemberClass' outside namespace enclosing 'A' is a Microsoft extension}}
+
+template <>
+enum A::X<int>::MemberEnumeration; // expected-warning {{member enumeration specialization of 'MemberEnumeration' outside namespace enclosing 'A' is a Microsoft extension}} // expected-error {{ISO C++ forbids forward references to 'enum' types}}
+
+}
+
diff --git a/test/SemaTemplate/friend.cpp b/test/SemaTemplate/friend.cpp
index e78a067ef8fa..ef1aed50e626 100644
--- a/test/SemaTemplate/friend.cpp
+++ b/test/SemaTemplate/friend.cpp
@@ -31,3 +31,19 @@ namespace PR6770 {
friend class f1; // expected-error{{'friend' used outside of class}}
}
}
+
+namespace friend_redecl_inline {
+// We had a bug where instantiating the foo friend declaration would check the
+// defined-ness of the most recent decl while checking if the canonical decl was
+// inlined.
+void foo();
+void bar();
+template <typename T>
+class C {
+ friend void foo();
+ friend inline void bar();
+};
+inline void foo() {}
+inline void bar() {}
+C<int> c;
+}
diff --git a/test/SemaTemplate/instantiate-local-class.cpp b/test/SemaTemplate/instantiate-local-class.cpp
index c9897b9c614b..f58d7a496225 100644
--- a/test/SemaTemplate/instantiate-local-class.cpp
+++ b/test/SemaTemplate/instantiate-local-class.cpp
@@ -1,4 +1,6 @@
// RUN: %clang_cc1 -verify -std=c++11 %s
+// RUN: %clang_cc1 -verify -std=c++11 -fdelayed-template-parsing %s
+
template<typename T>
void f0() {
struct X;
@@ -194,3 +196,201 @@ struct B {
void f() { F<int>(); }
};
}
+
+namespace PR23194 {
+ struct X {
+ int operator()() const { return 0; }
+ };
+ struct Y {
+ Y(int) {}
+ };
+ template <bool = true> int make_seed_pair() noexcept {
+ struct state_t {
+ X x;
+ Y y{x()};
+ };
+ return 0;
+ }
+ int func() {
+ return make_seed_pair();
+ }
+}
+
+namespace PR18653 {
+ // Forward declarations
+
+ template<typename T> void f1() {
+ void g1(struct x1);
+ struct x1 {};
+ }
+ template void f1<int>();
+
+ template<typename T> void f1a() {
+ void g1(union x1);
+ union x1 {};
+ }
+ template void f1a<int>();
+
+ template<typename T> void f2() {
+ void g2(enum x2); // expected-error{{ISO C++ forbids forward references to 'enum' types}}
+ enum x2 { nothing };
+ }
+ template void f2<int>();
+
+ template<typename T> void f3() {
+ void g3(enum class x3);
+ enum class x3 { nothing };
+ }
+ template void f3<int>();
+
+
+ template<typename T> void f4() {
+ void g4(struct x4 {} x); // expected-error{{'x4' cannot be defined in a parameter type}}
+ }
+ template void f4<int>();
+
+ template<typename T> void f4a() {
+ void g4(union x4 {} x); // expected-error{{'x4' cannot be defined in a parameter type}}
+ }
+ template void f4a<int>();
+
+
+ template <class T> void f();
+ template <class T> struct S1 {
+ void m() {
+ f<class newclass>();
+ f<union newunion>();
+ }
+ };
+ template struct S1<int>;
+
+ template <class T> struct S2 {
+ void m() {
+ f<enum new_enum>(); // expected-error{{ISO C++ forbids forward references to 'enum' types}}
+ }
+ };
+ template struct S2<int>;
+
+ template <class T> struct S3 {
+ void m() {
+ f<enum class new_enum>();
+ }
+ };
+ template struct S3<int>;
+
+ template <class T> struct S4 {
+ struct local {};
+ void m() {
+ f<local>();
+ }
+ };
+ template struct S4<int>;
+
+ template <class T> struct S4a {
+ union local {};
+ void m() {
+ f<local>();
+ }
+ };
+ template struct S4a<int>;
+
+ template <class T> struct S5 {
+ enum local { nothing };
+ void m() {
+ f<local>();
+ }
+ };
+ template struct S5<int>;
+
+ template <class T> struct S7 {
+ enum class local { nothing };
+ void m() {
+ f<local>();
+ }
+ };
+ template struct S7<int>;
+
+
+ template <class T> void fff(T *x);
+ template <class T> struct S01 {
+ struct local { };
+ void m() {
+ local x;
+ fff(&x);
+ }
+ };
+ template struct S01<int>;
+
+ template <class T> struct S01a {
+ union local { };
+ void m() {
+ local x;
+ fff(&x);
+ }
+ };
+ template struct S01a<int>;
+
+ template <class T> struct S02 {
+ enum local { nothing };
+ void m() {
+ local x;
+ fff(&x);
+ }
+ };
+ template struct S02<int>;
+
+ template <class T> struct S03 {
+ enum class local { nothing };
+ void m() {
+ local x;
+ fff(&x);
+ }
+ };
+ template struct S03<int>;
+
+
+ template <class T> struct S04 {
+ void m() {
+ struct { } x;
+ fff(&x);
+ }
+ };
+ template struct S04<int>;
+
+ template <class T> struct S04a {
+ void m() {
+ union { } x;
+ fff(&x);
+ }
+ };
+ template struct S04a<int>;
+
+ template <class T> struct S05 {
+ void m() {
+ enum { nothing } x;
+ fff(&x);
+ }
+ };
+ template struct S05<int>;
+
+ template <class T> struct S06 {
+ void m() {
+ class { virtual void mmm() {} } x;
+ fff(&x);
+ }
+ };
+ template struct S06<int>;
+}
+
+namespace PR20625 {
+template <typename T>
+void f() {
+ struct N {
+ static constexpr int get() { return 42; }
+ };
+ constexpr int n = N::get();
+ static_assert(n == 42, "n == 42");
+}
+
+void g() { f<void>(); }
+}
diff --git a/test/SemaTemplate/instantiate-non-dependent-types.cpp b/test/SemaTemplate/instantiate-non-dependent-types.cpp
index 432b9053bdca..1efd2a5844e8 100644
--- a/test/SemaTemplate/instantiate-non-dependent-types.cpp
+++ b/test/SemaTemplate/instantiate-non-dependent-types.cpp
@@ -21,7 +21,7 @@ public:
T *q = new T();
t.T::~T();
q->~T();
- // expected-error@+2 {{'int' is not a class, namespace, or scoped enumeration}}
+ // expected-error@+2 {{'int' is not a class, namespace, or enumeration}}
// expected-error@+1 {{no member named '~Colors' in 'Colors'}}
q->A::~A();
// expected-error@+2 {{no member named '~int' in 'Q'}}
diff --git a/test/SemaTemplate/instantiate-static-var.cpp b/test/SemaTemplate/instantiate-static-var.cpp
index f309f29eafab..a7b3433b3544 100644
--- a/test/SemaTemplate/instantiate-static-var.cpp
+++ b/test/SemaTemplate/instantiate-static-var.cpp
@@ -114,3 +114,15 @@ namespace PR6449 {
template class X1<char>;
}
+
+typedef char MyString[100];
+template <typename T>
+struct StaticVarWithTypedefString {
+ static MyString str;
+};
+template <typename T>
+MyString StaticVarWithTypedefString<T>::str = "";
+
+void testStaticVarWithTypedefString() {
+ (void)StaticVarWithTypedefString<int>::str;
+}
diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
index 979782f1cba8..62451081c3bc 100644
--- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -303,12 +303,12 @@ static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), "");
}
namespace two_types_in_base {
-template <typename T> struct A { typedef T NameFromBase; };
-template <typename T> struct B { struct NameFromBase { T m; }; };
+template <typename T> struct A { typedef T NameFromBase; }; // expected-note {{member found by ambiguous name lookup}}
+template <typename T> struct B { struct NameFromBase { T m; }; }; // expected-note {{member found by ambiguous name lookup}}
template <typename T> struct C : A<T>, B<T> {
- NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+ NameFromBase m; // expected-error {{member 'NameFromBase' found in multiple base classes of different types}} expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
};
-static_assert(sizeof(C<int>) == 4, "");
+static_assert(sizeof(C<int>) == 4, ""); // expected-note {{in instantiation of template class 'two_types_in_base::C<int>' requested here}}
}
namespace type_and_decl_in_base {
@@ -386,9 +386,66 @@ namespace type_in_base_of_dependent_base {
struct A { typedef int NameFromBase; };
template <typename T>
struct B : A {};
-// FIXME: MSVC accepts this.
template <typename T>
-struct C : B<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+struct C : B<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+}
+
+namespace type_in_second_dependent_base {
+template <typename T>
+struct A {};
+template<typename T>
+struct B { typedef T NameFromBase; };
+template <typename T>
+struct D : A<T>, B<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+}
+
+namespace type_in_second_non_dependent_base {
+struct A {};
+struct B { typedef int NameFromBase; };
+template<typename T>
+struct C : A, B {};
+template <typename T>
+struct D : C<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+}
+
+namespace type_in_virtual_base_of_dependent_base {
+template <typename T>
+struct A { typedef T NameFromBase; };
+template <typename T>
+struct B : virtual A<T> {};
+template <typename T>
+struct C : B<T>, virtual A<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+C<int> c;
+}
+
+namespace type_in_base_of_multiple_dependent_bases {
+template <typename T>
+struct A { typedef T NameFromBase; };
+template <typename T>
+struct B : public A<T> {};
+template <typename T>
+struct C : B<T>, public A<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-warning {{direct base 'A<int>' is inaccessible due to ambiguity:}}
+C<int> c; // expected-note {{in instantiation of template class 'type_in_base_of_multiple_dependent_bases::C<int>' requested here}}
+}
+
+namespace type_in_dependent_base_of_non_dependent_type {
+template<typename T> struct A { typedef int NameFromBase; };
+template<typename T> struct B : A<T> {
+ struct C;
+ template<typename TT>
+ struct D : C {
+ NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ };
+ struct E : C {
+ NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ };
+};
+template<typename T> struct B<T>::C : B {
+ NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+};
+template<typename T> struct F : B<T>::C {
+ NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+};
}
namespace lookup_in_function_contexts {
diff --git a/test/SemaTemplate/virtual-member-functions.cpp b/test/SemaTemplate/virtual-member-functions.cpp
index c2fc2634edd6..4044f9e513db 100644
--- a/test/SemaTemplate/virtual-member-functions.cpp
+++ b/test/SemaTemplate/virtual-member-functions.cpp
@@ -110,12 +110,12 @@ namespace PR7114 {
namespace DynamicCast {
struct Y {};
template<typename T> struct X : virtual Y {
- virtual void foo() { T x; } // expected-error {{variable has incomplete type 'void'}}
+ virtual void foo() { T x; }
};
template<typename T> struct X2 : virtual Y {
virtual void foo() { T x; }
};
- Y* f(X<void>* x) { return dynamic_cast<Y*>(x); } // expected-note {{in instantiation of member function 'DynamicCast::X<void>::foo' requested here}}
+ Y* f(X<void>* x) { return dynamic_cast<Y*>(x); }
Y* f2(X<void>* x) { return dynamic_cast<Y*>(x); }
}