diff options
Diffstat (limited to 'test/SemaTemplate')
19 files changed, 305 insertions, 11 deletions
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp index e44115c748c3..4cd43b469ae0 100644 --- a/test/SemaTemplate/class-template-spec.cpp +++ b/test/SemaTemplate/class-template-spec.cpp @@ -20,8 +20,7 @@ int test_incomplete_specs(A<double, double> *a1, A<double> *a2) { (void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}} - (void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}} \ - // expected-note{{first required here}} + (void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}} } typedef float FLOAT; @@ -71,8 +70,7 @@ namespace N { } // Diagnose specialization errors -struct A<double> { }; // expected-error{{template specialization requires 'template<>'}} \ - // expected-error{{after instantiation}} +struct A<double> { }; // expected-error{{template specialization requires 'template<>'}} template<> struct ::A<double>; @@ -100,3 +98,9 @@ template<> struct N::B<char> { int testf(int x) { return f(x); } }; +// PR5264 +template <typename T> class Foo; +Foo<int>* v; +Foo<int>& F() { return *v; } +template <typename T> class Foo {}; +Foo<int> x; diff --git a/test/SemaTemplate/constructor-template.cpp b/test/SemaTemplate/constructor-template.cpp index acd845bc2fd5..79bf7c585e34 100644 --- a/test/SemaTemplate/constructor-template.cpp +++ b/test/SemaTemplate/constructor-template.cpp @@ -51,3 +51,4 @@ void test_X1(X1<int> xi) { template<class C> struct A {}; template <> struct A<int>{A(const A<int>&);}; struct B { A<int> x; B(B& a) : x(a.x) {} }; + diff --git a/test/SemaTemplate/copy-ctor-assign.cpp b/test/SemaTemplate/copy-ctor-assign.cpp index 90fb0133a721..69481ea557f4 100644 --- a/test/SemaTemplate/copy-ctor-assign.cpp +++ b/test/SemaTemplate/copy-ctor-assign.cpp @@ -33,4 +33,20 @@ void test3(X<int> &x, X<int> xi, X<long> xl, X<int Y::*> xmptr) { x = xi; x = xl; x = xmptr; // expected-note{{instantiation}} -}
\ No newline at end of file +} + +struct X1 { + X1 &operator=(const X1&); +}; + +template<typename T> +struct X2 : X1 { + template<typename U> X2 &operator=(const U&); +}; + +struct X3 : X2<int> { +}; + +void test_X2(X3 &to, X3 from) { + to = from; +} diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp index 575283ed8b51..9c0f1ecf0c3b 100644 --- a/test/SemaTemplate/default-expr-arguments.cpp +++ b/test/SemaTemplate/default-expr-arguments.cpp @@ -84,3 +84,27 @@ struct X1 { void test_X1() { X1<int> x1; } + +// PR5283 +namespace PR5283 { +template<typename T> struct A { + A(T = 1); // expected-error 3 {{incompatible type initializing 'int', expected 'int *'}} +}; + +struct B : A<int*> { + B(); +}; +B::B() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}} + +struct C : virtual A<int*> { + C(); +}; +C::C() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}} + +struct D { + D(); + + A<int*> a; +}; +D::D() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}} +} diff --git a/test/SemaTemplate/ext-vector-type.cpp b/test/SemaTemplate/ext-vector-type.cpp index b6aebc102fb4..7cc4ae930ed2 100644 --- a/test/SemaTemplate/ext-vector-type.cpp +++ b/test/SemaTemplate/ext-vector-type.cpp @@ -45,3 +45,16 @@ struct make5 { typedef int_ptr __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector type}} }; +template<int Length> +struct make6 { + typedef int __attribute__((ext_vector_type(Length))) type; +}; + +int test_make6() { + make6<4>::type x; + x.w = 7; + + make6<2>::type y; + y.x = -1; + y.w = -1; // expected-error{{vector component access exceeds type}} +} diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp index 761c13076d2a..84a8e899dbea 100644 --- a/test/SemaTemplate/friend-template.cpp +++ b/test/SemaTemplate/friend-template.cpp @@ -54,6 +54,7 @@ struct X1 { template<typename U> void f2(U); X1<int> x1i; +X0<int*> x0ip; template<> void f2(int); @@ -62,3 +63,31 @@ template<> void f2(int); template<typename U> void f3(U); template<> void f3(int); + +// PR5332 +template <typename T> +class Foo { + template <typename U> + friend class Foo; +}; + +Foo<int> foo; + +template<typename T, T Value> +struct X2a; + +template<typename T, int Size> +struct X2b; + +template<typename T> +class X3 { + template<typename U, U Value> + friend struct X2a; + + template<typename U, T Value> + friend struct X2b; +}; + +X3<int> x3i; // okay + +X3<long> x3l; // FIXME: should cause an instantiation-time failure diff --git a/test/SemaTemplate/instantiate-cast.cpp b/test/SemaTemplate/instantiate-cast.cpp index 6b3fc6e12534..c3c318f36d5d 100644 --- a/test/SemaTemplate/instantiate-cast.cpp +++ b/test/SemaTemplate/instantiate-cast.cpp @@ -96,7 +96,6 @@ struct FunctionalCast1 { template struct FunctionalCast1<int, float>; template struct FunctionalCast1<A, int>; // expected-note{{instantiation}} -#if 0 // Generates temporaries, which we cannot handle yet. template<int N, long M> struct FunctionalCast2 { @@ -106,4 +105,13 @@ struct FunctionalCast2 { }; template struct FunctionalCast2<1, 3>; -#endif + +// --------------------------------------------------------------------- +// implicit casting +// --------------------------------------------------------------------- +template<typename T> +struct Derived2 : public Base { }; + +void test_derived_to_base(Base *&bp, Derived2<int> *dp) { + bp = dp; +} diff --git a/test/SemaTemplate/instantiate-declref-ice.cpp b/test/SemaTemplate/instantiate-declref-ice.cpp index 21ee87202797..ab12b90f6c98 100644 --- a/test/SemaTemplate/instantiate-declref-ice.cpp +++ b/test/SemaTemplate/instantiate-declref-ice.cpp @@ -5,3 +5,33 @@ template<int i> struct x { x<j>* y; }; +template<int i> +const int x<i>::j; + +int array0[x<2>::j]; + + +template<typename T> +struct X0 { + static const unsigned value = sizeof(T); +}; + +template<typename T> +const unsigned X0<T>::value; + +int array1[X0<int>::value == sizeof(int)? 1 : -1]; + +const unsigned& testX0() { return X0<int>::value; } + +int array2[X0<int>::value == sizeof(int)? 1 : -1]; + +template<typename T> +struct X1 { + static const unsigned value; +}; + +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}} diff --git a/test/SemaTemplate/instantiate-declref.cpp b/test/SemaTemplate/instantiate-declref.cpp index 051c6050abea..359e2c7dfaa4 100644 --- a/test/SemaTemplate/instantiate-declref.cpp +++ b/test/SemaTemplate/instantiate-declref.cpp @@ -69,3 +69,21 @@ namespace N2 { template struct N2::Outer2::Inner<float>; template struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}} + +// Test dependent pointer-to-member expressions. +template<typename T> +struct smart_ptr { + struct safe_bool { + int member; + }; + + operator int safe_bool::*() const { + return ptr? &safe_bool::member : 0; + } + + T* ptr; +}; + +void test_smart_ptr(smart_ptr<int> p) { + if (p) { } +} diff --git a/test/SemaTemplate/instantiate-function-1.mm b/test/SemaTemplate/instantiate-function-1.mm index be995e7ff615..c119ab5da8b9 100644 --- a/test/SemaTemplate/instantiate-function-1.mm +++ b/test/SemaTemplate/instantiate-function-1.mm @@ -1,5 +1,5 @@ // RUN: clang-cc -fsyntax-only -verify %s -// XFAIL +// XFAIL: * template<typename T> struct Member0 { void f(T t) { diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp index f7c09ef87900..df1e1d964eb6 100644 --- a/test/SemaTemplate/instantiate-method.cpp +++ b/test/SemaTemplate/instantiate-method.cpp @@ -81,3 +81,20 @@ int *a(A0<int> &x0, A1<int> &x1) { int *y0 = x0; int *y1 = x1; // expected-error{{initializing}} } + +struct X0Base { + int &f(); +}; + +template<typename T> +struct X0 : X0Base { +}; + +template<typename U> +struct X1 : X0<U> { + int &f2() { return X0Base::f(); } +}; + +void test_X1(X1<int> x1i) { + int &ir = x1i.f2(); +} diff --git a/test/SemaTemplate/instantiate-non-type-template-parameter.cpp b/test/SemaTemplate/instantiate-non-type-template-parameter.cpp new file mode 100644 index 000000000000..32acbd0d8bdc --- /dev/null +++ b/test/SemaTemplate/instantiate-non-type-template-parameter.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// PR5311 +template<typename T> +class StringSwitch { +public: + template<unsigned N> + void Case(const char (&S)[N], const int & Value) { + } +}; + +int main(int argc, char *argv[]) { + (void)StringSwitch<int>(); +} diff --git a/test/SemaTemplate/instantiate-subscript.cpp b/test/SemaTemplate/instantiate-subscript.cpp index 434d84e2b893..20e2c39d0cce 100644 --- a/test/SemaTemplate/instantiate-subscript.cpp +++ b/test/SemaTemplate/instantiate-subscript.cpp @@ -6,7 +6,7 @@ struct Sub0 { }; struct Sub1 { - long &operator[](long); + long &operator[](long); // expected-note{{candidate function}} }; struct ConvertibleToInt { @@ -24,3 +24,18 @@ template struct Subscript0<int*, int, int&>; template struct Subscript0<Sub0, int, int&>; template struct Subscript0<Sub1, ConvertibleToInt, long&>; template struct Subscript0<Sub1, Sub0, long&>; // expected-note{{instantiation}} + +// PR5345 +template <typename T> +struct S { + bool operator[](int n) const { return true; } +}; + +template <typename T> +void Foo(const S<int>& s, T x) { + if (s[0]) {} +} + +void Bar() { + Foo(S<int>(), 0); +} diff --git a/test/SemaTemplate/member-template-access-expr.cpp b/test/SemaTemplate/member-template-access-expr.cpp index 0f9f21f339d1..0238cd53c553 100644 --- a/test/SemaTemplate/member-template-access-expr.cpp +++ b/test/SemaTemplate/member-template-access-expr.cpp @@ -1,5 +1,4 @@ // RUN: clang-cc -fsyntax-only -verify %s - template<typename U, typename T> U f0(T t) { return t.template get<U>(); @@ -50,3 +49,47 @@ B<T>::destroy() void do_destroy_B(B<int> b) { b.destroy(); } + +struct X1 { + int* f1(int); + template<typename T> float* f1(T); + + static int* f2(int); + template<typename T> static float* f2(T); +}; + +void test_X1(X1 x1) { + float *fp1 = x1.f1<>(17); + float *fp2 = x1.f1<int>(3.14); + int *ip1 = x1.f1(17); + float *ip2 = x1.f1(3.14); + + float* (X1::*mf1)(int) = &X1::f1; + float* (X1::*mf2)(int) = &X1::f1<>; + float* (X1::*mf3)(float) = &X1::f1<float>; + + float* (*fp3)(int) = &X1::f2; + float* (*fp4)(int) = &X1::f2<>; + float* (*fp5)(float) = &X1::f2<float>; + float* (*fp6)(int) = X1::f2; + float* (*fp7)(int) = X1::f2<>; + float* (*fp8)(float) = X1::f2<float>; +} + +template<int A> struct X2 { + int m; +}; + +template<typename T> +struct X3 : T { }; + +template<typename T> +struct X4 { + template<typename U> + void f(X2<sizeof(X3<U>().U::m)>); +}; + +void f(X4<X3<int> > x4i) { + X2<sizeof(int)> x2; + x4i.f<X2<sizeof(int)> >(x2); +} diff --git a/test/SemaTemplate/nested-name-spec-template.cpp b/test/SemaTemplate/nested-name-spec-template.cpp index a5aa2dcb527a..1bdc7a89d4e8 100644 --- a/test/SemaTemplate/nested-name-spec-template.cpp +++ b/test/SemaTemplate/nested-name-spec-template.cpp @@ -1,4 +1,4 @@ -// RUN: clang-cc -fsyntax-only -verify %s +// RUN: clang-cc -fsyntax-only -verify -fms-extensions=0 %s namespace N { namespace M { diff --git a/test/SemaTemplate/nested-template.cpp b/test/SemaTemplate/nested-template.cpp index 5ee2c9954005..4d948184cee9 100644 --- a/test/SemaTemplate/nested-template.cpp +++ b/test/SemaTemplate/nested-template.cpp @@ -101,3 +101,10 @@ struct X0<T*> { template<typename U> void f(U u = T()) { } }; + +// PR5103 +template<typename> +struct X1 { + template<typename, bool = false> struct B { }; +}; +template struct X1<int>::B<bool>; diff --git a/test/SemaTemplate/operator-function-id-template.cpp b/test/SemaTemplate/operator-function-id-template.cpp new file mode 100644 index 000000000000..92a8c84e3be6 --- /dev/null +++ b/test/SemaTemplate/operator-function-id-template.cpp @@ -0,0 +1,28 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct A { + template<typename U> A<T> operator+(U); +}; + +template<int Value, typename T> bool operator==(A<T>, A<T>); + +template<> bool operator==<0>(A<int>, A<int>); + +bool test_qualified_id(A<int> ai) { + return ::operator==<0, int>(ai, ai); +} + +void test_op(A<int> a, int i) { + const A<int> &air = a.operator+<int>(i); +} + +template<typename T> +void test_op_template(A<T> at, T x) { + const A<T> &atr = at.template operator+<T>(x); + const A<T> &atr2 = at.A::template operator+<T>(x); + // FIXME: unrelated template-name instantiation issue + // const A<T> &atr3 = at.template A<T>::template operator+<T>(x); +} + +template void test_op_template<float>(A<float>, float); diff --git a/test/SemaTemplate/template-id-expr.cpp b/test/SemaTemplate/template-id-expr.cpp new file mode 100644 index 000000000000..a0cbe4408494 --- /dev/null +++ b/test/SemaTemplate/template-id-expr.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// PR5336 +template<typename FromCl> +struct isa_impl_cl { + template<class ToCl> + static void isa(const FromCl &Val) { } +}; + +template<class X, class Y> +void isa(const Y &Val) { return isa_impl_cl<Y>::template isa<X>(Val); } + +class Value; +void f0(const Value &Val) { isa<Value>(Val); } diff --git a/test/SemaTemplate/template-id-printing.cpp b/test/SemaTemplate/template-id-printing.cpp new file mode 100644 index 000000000000..13250943e92c --- /dev/null +++ b/test/SemaTemplate/template-id-printing.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -ast-print %s | FileCheck %s +namespace N { + template<typename T, typename U> void f(U); + template<int> void f(); +} + +void g() { + // CHECK: N::f<int>(3.14 + N::f<int>(3.14); + + // CHECK: N::f<double> + void (*fp)(int) = N::f<double>; +} |