diff options
Diffstat (limited to 'test/SemaTemplate')
| -rw-r--r-- | test/SemaTemplate/anonymous-union.cpp | 4 | ||||
| -rw-r--r-- | test/SemaTemplate/class-template-decl.cpp | 6 | ||||
| -rw-r--r-- | test/SemaTemplate/deduction.cpp | 5 | ||||
| -rw-r--r-- | test/SemaTemplate/dependent-names.cpp | 5 | ||||
| -rw-r--r-- | test/SemaTemplate/dependent-type-identity.cpp | 4 | ||||
| -rw-r--r-- | test/SemaTemplate/destructor-template.cpp | 10 | ||||
| -rw-r--r-- | test/SemaTemplate/explicit-specialization-member.cpp | 2 | ||||
| -rw-r--r-- | test/SemaTemplate/ext_ms_template_spec.cpp | 33 | ||||
| -rw-r--r-- | test/SemaTemplate/friend.cpp | 16 | ||||
| -rw-r--r-- | test/SemaTemplate/instantiate-local-class.cpp | 200 | ||||
| -rw-r--r-- | test/SemaTemplate/instantiate-non-dependent-types.cpp | 2 | ||||
| -rw-r--r-- | test/SemaTemplate/instantiate-static-var.cpp | 12 | ||||
| -rw-r--r-- | test/SemaTemplate/ms-lookup-template-base-classes.cpp | 69 | ||||
| -rw-r--r-- | test/SemaTemplate/virtual-member-functions.cpp | 4 |
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); } } |
