diff options
Diffstat (limited to 'test/SemaTemplate')
25 files changed, 469 insertions, 9 deletions
diff --git a/test/SemaTemplate/attributes.cpp b/test/SemaTemplate/attributes.cpp new file mode 100644 index 0000000..b696c5c --- /dev/null +++ b/test/SemaTemplate/attributes.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template<int N> +struct X { + struct __attribute__((__aligned__((N)))) Aligned { }; // expected-error{{'aligned' attribute requires integer constant}} + + int __attribute__((__address_space__(N))) *ptr; // expected-error{{attribute requires 1 argument(s)}} +}; diff --git a/test/SemaTemplate/current-instantiation.cpp b/test/SemaTemplate/current-instantiation.cpp index 4563748..c631dd7 100644 --- a/test/SemaTemplate/current-instantiation.cpp +++ b/test/SemaTemplate/current-instantiation.cpp @@ -151,3 +151,16 @@ struct X1 { X1<T*>::a = b; } }; + +namespace ConstantInCurrentInstantiation { + template<typename T> + struct X { + static const int value = 2; + static int array[value]; + }; + + template<typename T> const int X<T>::value; + + template<typename T> + int X<T>::array[X<T>::value] = { 1, 2 }; +} diff --git a/test/SemaTemplate/dependent-base-classes.cpp b/test/SemaTemplate/dependent-base-classes.cpp index d0dd9c9..e64d623 100644 --- a/test/SemaTemplate/dependent-base-classes.cpp +++ b/test/SemaTemplate/dependent-base-classes.cpp @@ -6,7 +6,7 @@ struct X0 : T::template apply<U> { }; template<typename T, typename U> -struct X1 : T::apply<U> { }; // expected-error{{missing 'template' keyword prior to dependent template name 'T::apply'}} +struct X1 : T::apply<U> { }; // expected-error{{use 'template' keyword to treat 'apply' as a dependent template name}} template<typename T> struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}} diff --git a/test/SemaTemplate/dependent-expr.cpp b/test/SemaTemplate/dependent-expr.cpp index 3f481b5..9fa7571 100644 --- a/test/SemaTemplate/dependent-expr.cpp +++ b/test/SemaTemplate/dependent-expr.cpp @@ -24,3 +24,19 @@ namespace PR6045 { (void)(k % member); } } + +namespace PR7198 { + struct A + { + ~A() { } + }; + + template<typename T> + struct B { + struct C : A {}; + void f() + { + C c = C(); + } + }; +} diff --git a/test/SemaTemplate/dependent-template-recover.cpp b/test/SemaTemplate/dependent-template-recover.cpp new file mode 100644 index 0000000..e91ffb5 --- /dev/null +++ b/test/SemaTemplate/dependent-template-recover.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +template<typename T, typename U, int N> +struct X { + void f(T* t) { + t->f0<U>(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}} + t->f0<int>(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}} + + t->operator+<U const, 1>(); // expected-error{{use 'template' keyword to treat 'operator +' as a dependent template name}} + t->f1<int const, 2>(); // expected-error{{use 'template' keyword to treat 'f1' as a dependent template name}} + + T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}} + t->T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}} + + // FIXME: We can't recover from these yet + (*t).f2<N>(); // expected-error{{expected expression}} + (*t).f2<0>(); // expected-error{{expected expression}} + } +}; diff --git a/test/SemaTemplate/dependent-type-identity.cpp b/test/SemaTemplate/dependent-type-identity.cpp index e095812..feffdcf 100644 --- a/test/SemaTemplate/dependent-type-identity.cpp +++ b/test/SemaTemplate/dependent-type-identity.cpp @@ -70,3 +70,19 @@ struct X1 { void f8(typename N::X2<U>::template apply<T> *); void f8(typename ::Nalias::X2<type>::template apply<U_type> *); // expected-error{{redeclar}} }; + +namespace PR6851 { + template <bool v> + struct S; + + struct N { + template <bool w> + S< S<w>::cond && 1 > foo(); + }; + + struct Alien; + bool operator&&(const Alien&, const Alien&); + + template <bool w> + S< S<w>::cond && 1 > N::foo() { } +} diff --git a/test/SemaTemplate/enum-argument.cpp b/test/SemaTemplate/enum-argument.cpp index de89487..7d23757 100644 --- a/test/SemaTemplate/enum-argument.cpp +++ b/test/SemaTemplate/enum-argument.cpp @@ -21,3 +21,16 @@ struct X0 { }; X0<int> x0i; + +namespace rdar8020920 { + template<typename T> + struct X { + enum { e0 = 32 }; + + unsigned long long bitfield : e0; + + void f(int j) { + bitfield + j; + } + }; +} diff --git a/test/SemaTemplate/instantiate-anonymous-union.cpp b/test/SemaTemplate/instantiate-anonymous-union.cpp index 7c75885..255454b 100644 --- a/test/SemaTemplate/instantiate-anonymous-union.cpp +++ b/test/SemaTemplate/instantiate-anonymous-union.cpp @@ -29,3 +29,21 @@ template <typename T> struct C { }; C<int> c0(0); + +namespace PR7088 { + template<typename T> + void f() { + union { + int a; + union { + float real; + T d; + }; + }; + + a = 17; + d = 3.14; + } + + template void f<double>(); +} diff --git a/test/SemaTemplate/instantiate-attr.cpp b/test/SemaTemplate/instantiate-attr.cpp index 7fb1736..e8291ed 100644 --- a/test/SemaTemplate/instantiate-attr.cpp +++ b/test/SemaTemplate/instantiate-attr.cpp @@ -2,6 +2,12 @@ template <typename T> struct A { char a __attribute__((aligned(16))); + + struct B { + typedef T __attribute__((aligned(16))) i16; + i16 x; + }; }; int a[sizeof(A<int>) == 16 ? 1 : -1]; +int a2[sizeof(A<int>::B) == 16 ? 1 : -1]; diff --git a/test/SemaTemplate/instantiate-complete.cpp b/test/SemaTemplate/instantiate-complete.cpp index d854c9e..c13930d 100644 --- a/test/SemaTemplate/instantiate-complete.cpp +++ b/test/SemaTemplate/instantiate-complete.cpp @@ -99,3 +99,32 @@ namespace TemporaryObjectCopy { template void f(int); } + +namespace PR7080 { + template <class T, class U> + class X + { + typedef char true_t; + class false_t { char dummy[2]; }; + static true_t dispatch(U); + static false_t dispatch(...); + static T trigger(); + public: + enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; + }; + + template <class T> + class rv : public T + { }; + + bool x = X<int, rv<int>&>::value; +} + +namespace pr7199 { + template <class T> class A; // expected-note {{template is declared here}} + template <class T> class B { + class A<T>::C field; // expected-error {{implicit instantiation of undefined template 'pr7199::A<int>'}} + }; + + template class B<int>; // expected-note {{in instantiation}} +} diff --git a/test/SemaTemplate/instantiate-declref-ice.cpp b/test/SemaTemplate/instantiate-declref-ice.cpp index e88b494..0f3c08b 100644 --- a/test/SemaTemplate/instantiate-declref-ice.cpp +++ b/test/SemaTemplate/instantiate-declref-ice.cpp @@ -31,5 +31,4 @@ struct X1 { template<typename T> const unsigned X1<T>::value = sizeof(T); -int array3[X1<int>::value == sizeof(int)? 1 : -1]; // expected-error{{variable length arrays are not permitted in C++}} \ -// expected-error{{variable length array declaration not allowed at file scope}} +int array3[X1<int>::value == sizeof(int)? 1 : -1]; // expected-error{{variable length array declaration not allowed at file scope}} diff --git a/test/SemaTemplate/instantiate-expr-2.cpp b/test/SemaTemplate/instantiate-expr-2.cpp index b91b398..eaa68dd 100644 --- a/test/SemaTemplate/instantiate-expr-2.cpp +++ b/test/SemaTemplate/instantiate-expr-2.cpp @@ -194,6 +194,37 @@ namespace N12 { void f0(int **a) { C::f0(a); } } +namespace PR7202 { + template<typename U, typename T> + struct meta { + typedef T type; + }; + + struct X { + struct dummy; + + template<typename T> + X(T, typename meta<T, dummy*>::type = 0); + + template<typename T, typename A> + X(T, A); + }; + + template<typename T> + struct Z { }; + + template<typename T> Z<T> g(T); + + struct Y { + template<typename T> + void f(T t) { + new X(g(*this)); + } + }; + + template void Y::f(int); +} + namespace N13 { class A{ A(const A&); diff --git a/test/SemaTemplate/instantiate-expr-3.cpp b/test/SemaTemplate/instantiate-expr-3.cpp index 41a96a3..d506b19 100644 --- a/test/SemaTemplate/instantiate-expr-3.cpp +++ b/test/SemaTemplate/instantiate-expr-3.cpp @@ -63,7 +63,7 @@ template struct Conditional0<int, int, int>; template<typename T> struct StatementExpr0 { void f(T t) { - (void)({ if (t) t = t + 17; t + 12;}); // expected-error{{invalid}} + (void)({ if (t) t = t + 17; t + 12;}); // expected-error{{contextually convertible}} } }; diff --git a/test/SemaTemplate/instantiate-field.cpp b/test/SemaTemplate/instantiate-field.cpp index 60d4b21..a260635 100644 --- a/test/SemaTemplate/instantiate-field.cpp +++ b/test/SemaTemplate/instantiate-field.cpp @@ -26,3 +26,58 @@ void test2(const X<float> *xf) { void test3(const X<int(int)> *xf) { (void)xf->x; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}} } + +namespace PR7123 { + template <class > struct requirement_; + + template <void(*)()> struct instantiate + { }; + + template <class > struct requirement ; + struct failed ; + + template <class Model> struct requirement<failed *Model::*> + { + static void failed() + { + ((Model*)0)->~Model(); // expected-note{{in instantiation of}} + } + }; + + template <class Model> struct requirement_<void(*)(Model)> : requirement<failed *Model::*> + { }; + + template <int> struct Requires_ + { typedef void type; }; + + template <class Model> struct usage_requirements + { + ~usage_requirements() + {((Model*)0)->~Model(); } // expected-note{{in instantiation of}} + }; + + template < typename TT > struct BidirectionalIterator + { + enum + { value = 0 }; + + instantiate< requirement_<void(*)(usage_requirements<BidirectionalIterator>)>::failed> int534; // expected-note{{in instantiation of}} + + ~BidirectionalIterator() + { i--; } // expected-error{{cannot decrement value of type 'PR7123::X'}} + + TT i; + }; + + struct X + { }; + + template<typename RanIter> + typename Requires_< BidirectionalIterator<RanIter>::value >::type sort(RanIter,RanIter){} + + void f() + { + X x; + sort(x,x); + } +} diff --git a/test/SemaTemplate/instantiate-function-2.cpp b/test/SemaTemplate/instantiate-function-2.cpp index 6318fac..afca358 100644 --- a/test/SemaTemplate/instantiate-function-2.cpp +++ b/test/SemaTemplate/instantiate-function-2.cpp @@ -10,3 +10,13 @@ void f() { S<int> s1; S<int> s2(10); } + +namespace PR7184 { + template<typename T> + void f() { + typedef T type; + void g(int array[sizeof(type)]); + } + + template void f<int>(); +} diff --git a/test/SemaTemplate/instantiate-member-pointers.cpp b/test/SemaTemplate/instantiate-member-pointers.cpp index 2308ac5..dca0f62 100644 --- a/test/SemaTemplate/instantiate-member-pointers.cpp +++ b/test/SemaTemplate/instantiate-member-pointers.cpp @@ -53,3 +53,15 @@ void accept_X4(X4<Member>); void test_accept_X4(X4<&Y::x> x4) { accept_X4(x4); } + +namespace ValueDepMemberPointer { + template <void (*)()> struct instantiate_function {}; + template <typename T> struct S { + static void instantiate(); + typedef instantiate_function<&S::instantiate> x; // expected-note{{instantiation}} + }; + template <typename T> void S<T>::instantiate() { + int a[(int)sizeof(T)-42]; // expected-error{{array size is negative}} + } + S<int> s; +} diff --git a/test/SemaTemplate/instantiate-non-dependent-types.cpp b/test/SemaTemplate/instantiate-non-dependent-types.cpp new file mode 100644 index 0000000..a0005c5 --- /dev/null +++ b/test/SemaTemplate/instantiate-non-dependent-types.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +template<typename T> +struct X1 { + static void member() { T* x = 1; } // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} +}; + +template<void(*)()> struct instantiate { }; + +template<typename T> +struct X2 { + typedef instantiate<&X1<int>::member> i; // expected-note{{in instantiation of}} +}; + +X2<int> x; diff --git a/test/SemaTemplate/instantiate-overload-candidates.cpp b/test/SemaTemplate/instantiate-overload-candidates.cpp new file mode 100644 index 0000000..5b7e60d --- /dev/null +++ b/test/SemaTemplate/instantiate-overload-candidates.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// This is the function actually selected during overload resolution, and the +// only one defined. +template <typename T> void f(T*, int) {} + +template <typename T> struct S; +template <typename T> struct S_ : S<T> { typedef int type; }; // expected-note{{in instantiation}} +template <typename T> struct S { + // Force T to have a complete type here so we can observe instantiations with + // incomplete types. + T t; // expected-error{{field has incomplete type}} +}; + +// Provide a bad class and an overload that instantiates templates with it. +class NoDefinition; // expected-note{{forward declaration}} +template <typename T> S_<NoDefinition>::type f(T*, NoDefinition*); // expected-note{{in instantiation}} + +void test(int x) { + f(&x, 0); +} diff --git a/test/SemaTemplate/nested-name-spec-template.cpp b/test/SemaTemplate/nested-name-spec-template.cpp index 9d25a05..54e615b 100644 --- a/test/SemaTemplate/nested-name-spec-template.cpp +++ b/test/SemaTemplate/nested-name-spec-template.cpp @@ -64,3 +64,10 @@ namespace test1 { template <class T> T pair<T>::* const pair<T>::mem_array[2] = { &pair<T>::x, &pair<T>::y }; } + +typedef int T; +namespace N1 { + template<typename T> T f0(); +} + +template<typename T> T N1::f0() { } diff --git a/test/SemaTemplate/overload-candidates.cpp b/test/SemaTemplate/overload-candidates.cpp new file mode 100644 index 0000000..8762cc8 --- /dev/null +++ b/test/SemaTemplate/overload-candidates.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template<typename T> +const T& min(const T&, const T&); // expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'long')}} + +void test_min() { + (void)min(1, 2l); // expected-error{{no matching function for call to 'min'}} +} + +template<typename R, typename T> +R *dyn_cast(const T&); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}} + +void test_dyn_cast(int* ptr) { + (void)dyn_cast(ptr); // expected-error{{no matching function for call to 'dyn_cast'}} +} + +template<int I, typename T> + void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I'}} +template<template<class T> class, typename T> + void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}} + +void test_get(void *ptr) { + get<int>(ptr); // expected-error{{no matching function for call to 'get'}} +} + +template<typename T> + typename T::type get_type(const T&); // expected-note{{candidate template ignored: substitution failure [with T = int *]}} + +void test_get_type(int *ptr) { + (void)get_type(ptr); // expected-error{{no matching function for call to 'get_type'}} +} + +struct X { + template<typename T> + const T& min(const T&, const T&); // expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'long')}} +}; + +void test_X_min(X x) { + (void)x.min(1, 2l); // expected-error{{no matching member function for call to 'min'}} +} diff --git a/test/SemaTemplate/partial-spec-instantiate.cpp b/test/SemaTemplate/partial-spec-instantiate.cpp index 3156892..68b4964 100644 --- a/test/SemaTemplate/partial-spec-instantiate.cpp +++ b/test/SemaTemplate/partial-spec-instantiate.cpp @@ -18,3 +18,23 @@ struct X2<U*> { }; void a(char *a, char *b) {X2<char*>::f();} + +namespace WonkyAccess { + template<typename T> + struct X { + int m; + }; + + template<typename U> + class Y; + + template<typename U> + struct Y<U*> : X<U> { }; + + template<> + struct Y<float*> : X<float> { }; + + int f(Y<int*> y, Y<float*> y2) { + return y.m + y2.m; + } +} diff --git a/test/SemaTemplate/temp_explicit.cpp b/test/SemaTemplate/temp_explicit.cpp index fbb41ff..76244c2 100644 --- a/test/SemaTemplate/temp_explicit.cpp +++ b/test/SemaTemplate/temp_explicit.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++0x-compat %s // // Tests explicit instantiation of templates. template<typename T, typename U = T> class X0 { }; @@ -125,3 +125,27 @@ template <> // expected-warning{{extraneous template parameter list}} template <> struct Foo<int>::Bar<void> {}; + +namespace N1 { + + template<typename T> struct X7 { }; // expected-note{{here}} + + namespace Inner { + template<typename T> struct X8 { }; + } + + template struct X7<int>; + template struct Inner::X8<int>; +} + +template<typename T> struct X9 { }; // expected-note{{here}} + +template struct ::N1::Inner::X8<float>; + +namespace N2 { + using namespace N1; + + template struct X7<double>; // expected-warning{{must occur in namespace}} + + template struct X9<float>; // expected-warning{{must occur in the global}} +} diff --git a/test/SemaTemplate/template-id-expr.cpp b/test/SemaTemplate/template-id-expr.cpp index b3f41be..de8d7f6 100644 --- a/test/SemaTemplate/template-id-expr.cpp +++ b/test/SemaTemplate/template-id-expr.cpp @@ -44,3 +44,41 @@ struct X { }; template struct X<3>; + +// 'template' as a disambiguator. +// PR7030 +struct Y0 { + template<typename U> + void f1(U); + + template<typename U> + static void f2(U); + + void f3(int); + + static int f4(int); + template<typename U> + static void f4(U); + + template<typename U> + void f() { + Y0::template f1<U>(0); + Y0::template f1(0); + this->template f1(0); + + Y0::template f2<U>(0); + Y0::template f2(0); + + Y0::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} + Y0::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} + + int x; + x = Y0::f4(0); + x = Y0::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} + x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} + + x = this->f4(0); + x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} + x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} + } +}; diff --git a/test/SemaTemplate/unused-variables.cpp b/test/SemaTemplate/unused-variables.cpp new file mode 100644 index 0000000..1b9350b --- /dev/null +++ b/test/SemaTemplate/unused-variables.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused -verify %s + +struct X0 { + ~X0(); +}; + +struct X1 { }; + +template<typename T> +void f() { + X0 x0; + X1 x1; // expected-warning{{unused variable 'x1'}} +} + +template<typename T, typename U> +void g() { + T t; + U u; // expected-warning{{unused variable 'u'}} +} + +template void g<X0, X1>(); // expected-note{{in instantiation of}} diff --git a/test/SemaTemplate/virtual-member-functions.cpp b/test/SemaTemplate/virtual-member-functions.cpp index 59df3c2..974f664 100644 --- a/test/SemaTemplate/virtual-member-functions.cpp +++ b/test/SemaTemplate/virtual-member-functions.cpp @@ -3,7 +3,7 @@ namespace PR5557 { template <class T> struct A { A(); - virtual void anchor(); // expected-note{{instantiation}} + virtual void anchor(); virtual int a(T x); }; template<class T> A<T>::A() {} @@ -14,7 +14,7 @@ template<class T> int A<T>::a(T x) { } void f(A<int> x) { - x.anchor(); + x.anchor(); // expected-note{{instantiation}} } template<typename T> @@ -43,7 +43,7 @@ template struct Derived<int>; // expected-note {{in instantiation of member func template<typename T> struct HasOutOfLineKey { - HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}} + HasOutOfLineKey() { } virtual T *f(float *fp); }; @@ -52,4 +52,35 @@ T *HasOutOfLineKey<T>::f(float *fp) { return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}} } -HasOutOfLineKey<int> out_of_line; +HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}} + +namespace std { + class type_info; +} + +namespace PR7114 { + class A { virtual ~A(); }; // expected-note{{declared private here}} + + template<typename T> + class B { + public: + class Inner : public A { }; // expected-error{{base class 'PR7114::A' has private destructor}} + static Inner i; + static const unsigned value = sizeof(i) == 4; + }; + + int f() { return B<int>::value; } + + void test_typeid(B<float>::Inner bfi) { + (void)typeid(bfi); // expected-note{{implicit default destructor}} + } + + template<typename T> + struct X : A { + void f() { } + }; + + void test_X(X<int> xi, X<float> xf) { + xi.f(); + } +} |