aboutsummaryrefslogtreecommitdiff
path: root/test/SemaTemplate
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r--test/SemaTemplate/class-template-spec.cpp12
-rw-r--r--test/SemaTemplate/constructor-template.cpp1
-rw-r--r--test/SemaTemplate/copy-ctor-assign.cpp18
-rw-r--r--test/SemaTemplate/default-expr-arguments.cpp24
-rw-r--r--test/SemaTemplate/ext-vector-type.cpp13
-rw-r--r--test/SemaTemplate/friend-template.cpp29
-rw-r--r--test/SemaTemplate/instantiate-cast.cpp12
-rw-r--r--test/SemaTemplate/instantiate-declref-ice.cpp30
-rw-r--r--test/SemaTemplate/instantiate-declref.cpp18
-rw-r--r--test/SemaTemplate/instantiate-function-1.mm2
-rw-r--r--test/SemaTemplate/instantiate-method.cpp17
-rw-r--r--test/SemaTemplate/instantiate-non-type-template-parameter.cpp14
-rw-r--r--test/SemaTemplate/instantiate-subscript.cpp17
-rw-r--r--test/SemaTemplate/member-template-access-expr.cpp45
-rw-r--r--test/SemaTemplate/nested-name-spec-template.cpp2
-rw-r--r--test/SemaTemplate/nested-template.cpp7
-rw-r--r--test/SemaTemplate/operator-function-id-template.cpp28
-rw-r--r--test/SemaTemplate/template-id-expr.cpp14
-rw-r--r--test/SemaTemplate/template-id-printing.cpp13
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>;
+}