summaryrefslogtreecommitdiff
path: root/test/SemaTemplate
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r--test/SemaTemplate/alias-templates.cpp32
-rw-r--r--test/SemaTemplate/atomics.cpp8
-rw-r--r--test/SemaTemplate/canonical-expr-type-0x.cpp21
-rw-r--r--test/SemaTemplate/class-template-ctor-initializer.cpp2
-rw-r--r--test/SemaTemplate/class-template-decl.cpp21
-rw-r--r--test/SemaTemplate/class-template-spec.cpp12
-rw-r--r--test/SemaTemplate/constexpr-instantiate.cpp77
-rw-r--r--test/SemaTemplate/crash-10438657.cpp15
-rw-r--r--test/SemaTemplate/deduction-crash.cpp2
-rw-r--r--test/SemaTemplate/delegating-constructors.cpp13
-rw-r--r--test/SemaTemplate/enum-forward.cpp2
-rw-r--r--test/SemaTemplate/explicit-instantiation.cpp10
-rw-r--r--test/SemaTemplate/friend-template.cpp19
-rw-r--r--test/SemaTemplate/friend.cpp2
-rw-r--r--test/SemaTemplate/instantiate-complete.cpp2
-rw-r--r--test/SemaTemplate/instantiate-declref-ice.cpp2
-rw-r--r--test/SemaTemplate/instantiate-expr-1.cpp11
-rw-r--r--test/SemaTemplate/instantiate-expr-4.cpp10
-rw-r--r--test/SemaTemplate/instantiate-expr-5.cpp2
-rw-r--r--test/SemaTemplate/instantiate-function-1.cpp2
-rw-r--r--test/SemaTemplate/instantiate-member-class.cpp22
-rw-r--r--test/SemaTemplate/instantiate-self.cpp89
-rw-r--r--test/SemaTemplate/instantiate-sizeof.cpp10
-rw-r--r--test/SemaTemplate/instantiate-static-var.cpp3
-rw-r--r--test/SemaTemplate/instantiate-typeof.cpp10
-rw-r--r--test/SemaTemplate/instantiation-depth.cpp4
-rw-r--r--test/SemaTemplate/instantiation-order.cpp15
-rw-r--r--test/SemaTemplate/member-access-ambig.cpp10
-rw-r--r--test/SemaTemplate/member-template-access-expr.cpp2
-rw-r--r--test/SemaTemplate/ms-if-exists.cpp68
-rw-r--r--test/SemaTemplate/ms-lookup-template-base-classes.cpp116
-rw-r--r--test/SemaTemplate/nested-incomplete-class.cpp21
-rw-r--r--test/SemaTemplate/nested-template.cpp13
-rw-r--r--test/SemaTemplate/pragma-ms_struct.cpp10
-rw-r--r--test/SemaTemplate/qualified-id.cpp9
-rw-r--r--test/SemaTemplate/resolve-single-template-id.cpp4
-rw-r--r--test/SemaTemplate/temp_arg_template.cpp6
-rw-r--r--test/SemaTemplate/temp_class_spec_neg.cpp2
-rw-r--r--test/SemaTemplate/temp_explicit.cpp8
-rw-r--r--test/SemaTemplate/temp_explicit_cxx0x.cpp2
-rw-r--r--test/SemaTemplate/template-id-expr.cpp14
-rw-r--r--test/SemaTemplate/template-id-printing.cpp128
42 files changed, 799 insertions, 32 deletions
diff --git a/test/SemaTemplate/alias-templates.cpp b/test/SemaTemplate/alias-templates.cpp
index 79d6849a6efe..75615ee29517 100644
--- a/test/SemaTemplate/alias-templates.cpp
+++ b/test/SemaTemplate/alias-templates.cpp
@@ -68,3 +68,35 @@ itt::thing ith(itr);
itt::rebind<bool> btr;
itt::rebind_thing<bool> btt(btr);
+
+namespace PR11848 {
+ template<typename T> using U = int;
+
+ template<typename T, typename ...Ts>
+ void f(U<T> i, U<Ts> ...is) { // expected-error {{type 'U<Ts>' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}}
+ return i + f<Ts...>(is...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}}
+ }
+
+ template<typename ...Ts>
+ struct S {
+ S(U<Ts>...ts); // expected-error {{does not contain any unexpanded parameter packs}}
+ };
+
+ template<typename T>
+ struct Hidden1 {
+ template<typename ...Ts>
+ Hidden1(typename T::template U<Ts> ...ts); // expected-error{{type 'typename Hide::U<Ts>' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}}
+ };
+
+ template<typename T, typename ...Ts>
+ struct Hidden2 {
+ Hidden2(typename T::template U<Ts> ...ts);
+ };
+
+ struct Hide {
+ template<typename T> using U = int;
+ };
+
+ Hidden1<Hide> h1; // expected-note{{in instantiation of template class 'PR11848::Hidden1<PR11848::Hide>' requested here}}
+ Hidden2<Hide, double, char> h2(1, 2);
+}
diff --git a/test/SemaTemplate/atomics.cpp b/test/SemaTemplate/atomics.cpp
index 7165bbe591e9..e9fdc9de3d23 100644
--- a/test/SemaTemplate/atomics.cpp
+++ b/test/SemaTemplate/atomics.cpp
@@ -6,3 +6,11 @@ template<typename T> T f(T* value) {
}
int g(long long* x) { return f(x); }
int g(int* x) { return f(x); }
+
+namespace PR11320 {
+ template<typename T>
+ void g(unsigned *x) {
+ __sync_bool_compare_and_swap(x, 1, 4);
+ }
+ void h() { g<int>(0); }
+}
diff --git a/test/SemaTemplate/canonical-expr-type-0x.cpp b/test/SemaTemplate/canonical-expr-type-0x.cpp
index 94ae360b43ef..d7379eadab1a 100644
--- a/test/SemaTemplate/canonical-expr-type-0x.cpp
+++ b/test/SemaTemplate/canonical-expr-type-0x.cpp
@@ -2,15 +2,24 @@
void f();
-// FIXME: would like to refer to the first function parameter in these test,
-// but that won't work (yet).
-
// Test typeof(expr) canonicalization
template<typename T, T N>
-void f0(T x, decltype(f(N)) y) { } // expected-note{{previous}}
+void f0(T x, decltype(f(N, x)) y) { } // expected-note{{previous}}
template<typename T, T N>
-void f0(T x, decltype((f)(N)) y) { }
+void f0(T x, decltype((f)(N, x)) y) { }
template<typename U, U M>
-void f0(U u, decltype(f(M))) { } // expected-error{{redefinition}}
+void f0(U u, decltype(f(M, u))) { } // expected-error{{redefinition}}
+
+// PR12438: Test sizeof...() canonicalization
+template<int> struct N {};
+
+template<typename...T>
+N<sizeof...(T)> f1() {} // expected-note{{previous}}
+
+template<typename, typename...T>
+N<sizeof...(T)> f1() {}
+
+template<class...U>
+N<sizeof...(U)> f1() {} // expected-error{{redefinition}}
diff --git a/test/SemaTemplate/class-template-ctor-initializer.cpp b/test/SemaTemplate/class-template-ctor-initializer.cpp
index 81a5e2b9c662..44bb4bda791e 100644
--- a/test/SemaTemplate/class-template-ctor-initializer.cpp
+++ b/test/SemaTemplate/class-template-ctor-initializer.cpp
@@ -49,7 +49,7 @@ namespace PR7259 {
int
main (void)
{
- Final final();
+ Final final;
return 0;
}
}
diff --git a/test/SemaTemplate/class-template-decl.cpp b/test/SemaTemplate/class-template-decl.cpp
index 2e84e93ead97..ec4e0163855c 100644
--- a/test/SemaTemplate/class-template-decl.cpp
+++ b/test/SemaTemplate/class-template-decl.cpp
@@ -74,3 +74,24 @@ namespace PR8001 {
Foo<int>::Bar<int> y(x);
}
}
+
+namespace rdar9676205 {
+ template <unsigned, class _Tp> class tuple_element;
+
+ template <class _T1, class _T2> class pair;
+
+ template <class _T1, class _T2>
+ class tuple_element<0, pair<_T1, _T2> >
+ {
+ template <class _Tp>
+ struct X
+ {
+ template <class _Up, bool = X<_Up>::value>
+ struct Y
+ : public X<_Up>,
+ public Y<_Up>
+ { };
+ };
+ };
+}
+
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp
index 07a5e2982c7f..f9015b37ea09 100644
--- a/test/SemaTemplate/class-template-spec.cpp
+++ b/test/SemaTemplate/class-template-spec.cpp
@@ -86,7 +86,7 @@ namespace N {
template<> struct N::B<int> { }; // okay
-template<> struct N::B<float> { }; // expected-warning{{originally}}
+template<> struct N::B<float> { }; // expected-warning{{C++11 extension}}
namespace M {
template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
@@ -109,3 +109,13 @@ Foo<int> x;
// Template template parameters
template<template<class T> class Wibble>
class Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}}
+
+namespace rdar9676205 {
+ template<typename T>
+ struct X {
+ template<typename U>
+ struct X<U*> { // expected-error{{explicit specialization of 'X' in class scope}}
+ };
+ };
+
+}
diff --git a/test/SemaTemplate/constexpr-instantiate.cpp b/test/SemaTemplate/constexpr-instantiate.cpp
new file mode 100644
index 000000000000..2f9fe0e4855b
--- /dev/null
+++ b/test/SemaTemplate/constexpr-instantiate.cpp
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+namespace UseBeforeDefinition {
+ struct A {
+ template<typename T> static constexpr T get() { return T(); }
+ // ok, not a constant expression.
+ int n = get<int>();
+ };
+
+ // ok, constant expression.
+ constexpr int j = A::get<int>();
+
+ template<typename T> constexpr int consume(T);
+ // ok, not a constant expression.
+ const int k = consume(0); // expected-note {{here}}
+
+ template<typename T> constexpr int consume(T) { return 0; }
+ // ok, constant expression.
+ constexpr int l = consume(0);
+
+ constexpr int m = k; // expected-error {{constant expression}} expected-note {{initializer of 'k'}}
+}
+
+namespace IntegralConst {
+ template<typename T> constexpr T f(T n) { return n; }
+ enum E {
+ v = f(0), w = f(1) // ok
+ };
+ static_assert(w == 1, "");
+
+ char arr[f('x')]; // ok
+ static_assert(sizeof(arr) == 'x', "");
+}
+
+namespace ConvertedConst {
+ template<typename T> constexpr T f(T n) { return n; }
+ int f() {
+ switch (f()) {
+ case f(4): return 0;
+ }
+ return 1;
+ }
+}
+
+namespace OverloadResolution {
+ template<typename T> constexpr T f(T t) { return t; }
+
+ template<int n> struct S { };
+
+ template<typename T> auto g(T t) -> S<f(sizeof(T))> &;
+ char &f(...);
+
+ template<typename T> auto h(T t[f(sizeof(T))]) -> decltype(&*t) {
+ return t;
+ }
+
+ S<4> &k = g(0);
+ int *p, *q = h(p);
+}
+
+namespace DataMember {
+ template<typename T> struct S { static const int k; };
+ const int n = S<int>::k; // expected-note {{here}}
+ template<typename T> const int S<T>::k = 0;
+ constexpr int m = S<int>::k; // ok
+ constexpr int o = n; // expected-error {{constant expression}} expected-note {{initializer of 'n'}}
+}
+
+namespace Reference {
+ const int k = 5;
+ template<typename T> struct S {
+ static volatile int &r;
+ };
+ template<typename T> volatile int &S<T>::r = const_cast<volatile int&>(k);
+ constexpr int n = const_cast<int&>(S<int>::r);
+ static_assert(n == 5, "");
+}
diff --git a/test/SemaTemplate/crash-10438657.cpp b/test/SemaTemplate/crash-10438657.cpp
new file mode 100644
index 000000000000..2ee64bdfcdbb
--- /dev/null
+++ b/test/SemaTemplate/crash-10438657.cpp
@@ -0,0 +1,15 @@
+// RUN: not %clang_cc1 -fsyntax-only %s 2> %t
+// RUN: FileCheck %s < %t
+// CHECK: 10 errors
+template<typename _CharT>
+class collate : public locale::facet {
+
+protected:
+virtual ~collate() {}
+ class wxObject;
+ class __attribute__ ((visibility("default"))) wxGDIRefData
+ : public wxObjectRefData {};
+ class __attribute__ ((visibility("default"))) wxGDIObject : public wxObject { \
+ public:
+ virtual bool IsOk() const {
+ return m_refData && static_cast<wxGDIRefData *>(m_refData)->IsOk();
diff --git a/test/SemaTemplate/deduction-crash.cpp b/test/SemaTemplate/deduction-crash.cpp
index fb23eda5bb9d..cf3899f5eda7 100644
--- a/test/SemaTemplate/deduction-crash.cpp
+++ b/test/SemaTemplate/deduction-crash.cpp
@@ -2,7 +2,7 @@
// Note that the error count below doesn't matter. We just want to
// make sure that the parser doesn't crash.
-// CHECK: 14 errors
+// CHECK: 13 errors
// PR7511
template<a>
diff --git a/test/SemaTemplate/delegating-constructors.cpp b/test/SemaTemplate/delegating-constructors.cpp
index d82343402b74..e177b50375f0 100644
--- a/test/SemaTemplate/delegating-constructors.cpp
+++ b/test/SemaTemplate/delegating-constructors.cpp
@@ -15,4 +15,17 @@ namespace PR10457 {
void f() {
string s("hello");
}
+
+ struct Foo {
+ Foo(int) { }
+
+
+ template <typename T>
+ Foo(T, int i) : Foo(i) { }
+};
+
+ void test_Foo()
+ {
+ Foo f(1, 1);
+ }
}
diff --git a/test/SemaTemplate/enum-forward.cpp b/test/SemaTemplate/enum-forward.cpp
index 3a4f05c0baa4..b25c21fc4635 100644
--- a/test/SemaTemplate/enum-forward.cpp
+++ b/test/SemaTemplate/enum-forward.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fms-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -fms-compatibility %s
template<typename T>
struct X {
diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp
index 63016fd71568..13d76befe289 100644
--- a/test/SemaTemplate/explicit-instantiation.cpp
+++ b/test/SemaTemplate/explicit-instantiation.cpp
@@ -94,6 +94,14 @@ namespace PR7622 {
template<typename,typename>
struct basic_streambuf{friend bob<>()}; // expected-error{{unknown type name 'bob'}} \
- // expected-error{{ expected member name or ';' after declaration specifiers}}
+ // expected-error{{expected member name or ';' after declaration specifiers}}
template struct basic_streambuf<int>;
}
+
+// Test that we do not crash.
+class TC1 {
+ class TC2 {
+ template // FIXME: error here.
+ void foo() { }
+ };
+};
diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp
index d1284de35f18..9c95fa0151c1 100644
--- a/test/SemaTemplate/friend-template.cpp
+++ b/test/SemaTemplate/friend-template.cpp
@@ -224,3 +224,22 @@ namespace friend_type_template_no_tag {
};
template struct S<int>;
}
+
+namespace PR10660 {
+ struct A {
+ template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
+ };
+}
+
+namespace rdar11147355 {
+ template <class T>
+ struct A {
+ template <class U> class B;
+ template <class S> template <class U> friend class A<S>::B;
+ };
+
+ template <class S> template <class U> class A<S>::B {
+ };
+
+ A<double>::B<double> ab;
+}
diff --git a/test/SemaTemplate/friend.cpp b/test/SemaTemplate/friend.cpp
index 99685f2396cf..e78a067ef8fa 100644
--- a/test/SemaTemplate/friend.cpp
+++ b/test/SemaTemplate/friend.cpp
@@ -28,6 +28,6 @@ namespace PR6770 {
template <class T>
void f() {
friend class f; // expected-error{{'friend' used outside of class}}
- friend class f1; // expected-error{{ 'friend' used outside of class}}
+ friend class f1; // expected-error{{'friend' used outside of class}}
}
}
diff --git a/test/SemaTemplate/instantiate-complete.cpp b/test/SemaTemplate/instantiate-complete.cpp
index 4b27da7349f9..68d5ae3cfb48 100644
--- a/test/SemaTemplate/instantiate-complete.cpp
+++ b/test/SemaTemplate/instantiate-complete.cpp
@@ -28,7 +28,6 @@ void test_subscript(X<double> *ptr1, X<int(int)> *ptr2, int i) {
void test_arith(X<signed char> *ptr1, X<unsigned char> *ptr2,
X<char(char)> *ptr3, X<short(short)> *ptr4) {
(void)(ptr1 + 5);
- // FIXME: if I drop the ')' after void, below, it still parses (!)
(void)(5 + ptr2);
(void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X<char (char)>' requested here}}
(void)(5 + ptr4); // expected-note{{in instantiation of template class 'X<short (short)>' requested here}}
@@ -145,4 +144,3 @@ namespace PR8425 {
BaseT<int> bt(ft);
}
}
-
diff --git a/test/SemaTemplate/instantiate-declref-ice.cpp b/test/SemaTemplate/instantiate-declref-ice.cpp
index 0f3c08b05620..49b1b63f5152 100644
--- a/test/SemaTemplate/instantiate-declref-ice.cpp
+++ b/test/SemaTemplate/instantiate-declref-ice.cpp
@@ -31,4 +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 array declaration not allowed at file scope}}
+int array3[X1<int>::value == sizeof(int)? 1 : -1];
diff --git a/test/SemaTemplate/instantiate-expr-1.cpp b/test/SemaTemplate/instantiate-expr-1.cpp
index 896437488d68..9395117e9ce4 100644
--- a/test/SemaTemplate/instantiate-expr-1.cpp
+++ b/test/SemaTemplate/instantiate-expr-1.cpp
@@ -34,7 +34,7 @@ void test_BitfieldMinus() {
template<int I, int J>
struct BitfieldDivide {
- int bitfield : I / J; // expected-error{{expression is not an integer constant expression}} \
+ int bitfield : I / J; // expected-error{{expression is not an integral constant expression}} \
// expected-note{{division by zero}}
};
@@ -167,8 +167,15 @@ namespace PR6424 {
new X(); // expected-note{{instantiation of}}
}
};
-
+
template void Y2<3>::f();
+
+ template<typename T>
+ void rdar10283928(int count) {
+ (void)new char[count]();
+ }
+
+ template void rdar10283928<int>(int);
}
namespace PR10864 {
diff --git a/test/SemaTemplate/instantiate-expr-4.cpp b/test/SemaTemplate/instantiate-expr-4.cpp
index 9483f9b28366..d95ccfecd9b5 100644
--- a/test/SemaTemplate/instantiate-expr-4.cpp
+++ b/test/SemaTemplate/instantiate-expr-4.cpp
@@ -282,6 +282,16 @@ template struct ArrowMemRef0<ArrowWrapper<MemIntFunc*>, int (*)(int)>;
template struct ArrowMemRef0<ArrowWrapper<MemInt*>, float&>; // expected-note{{instantiation}}
template struct ArrowMemRef0<ArrowWrapper<ArrowWrapper<MemInt*> >, int&>;
+struct UnresolvedMemRefArray {
+ int f(int);
+ int f(char);
+};
+UnresolvedMemRefArray Arr[10];
+template<typename U> int UnresolvedMemRefArrayT(U u) {
+ return Arr->f(u);
+}
+template int UnresolvedMemRefArrayT<int>(int);
+
// FIXME: we should be able to return a MemInt without the reference!
MemInt &createMemInt(int);
diff --git a/test/SemaTemplate/instantiate-expr-5.cpp b/test/SemaTemplate/instantiate-expr-5.cpp
index 6cdedda4d880..13b7eae21fd4 100644
--- a/test/SemaTemplate/instantiate-expr-5.cpp
+++ b/test/SemaTemplate/instantiate-expr-5.cpp
@@ -6,7 +6,7 @@ int y() { return x<int>(1); }
namespace PR5880 {
template<typename T>
struct A {
- static const int a = __builtin_offsetof(T, a.array[5].m); // expected-error{{error: no member named 'a' in 'HasM'}}
+ static const int a = __builtin_offsetof(T, a.array[5].m); // expected-error{{no member named 'a' in 'HasM'}}
};
struct HasM {
float m;
diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp
index 5406fbcd1baf..ceef27437748 100644
--- a/test/SemaTemplate/instantiate-function-1.cpp
+++ b/test/SemaTemplate/instantiate-function-1.cpp
@@ -194,7 +194,7 @@ template struct IndirectGoto0<int>; // expected-note{{instantiation}}
template<typename T> struct TryCatch0 {
void f() {
try {
- } catch (T t) { // expected-warning{{incomplete type}} \
+ } catch (T t) { // expected-error{{incomplete type}} \
// expected-error{{abstract class}}
} catch (...) {
}
diff --git a/test/SemaTemplate/instantiate-member-class.cpp b/test/SemaTemplate/instantiate-member-class.cpp
index c67eb4022a47..bb6427670c3e 100644
--- a/test/SemaTemplate/instantiate-member-class.cpp
+++ b/test/SemaTemplate/instantiate-member-class.cpp
@@ -118,3 +118,25 @@ namespace AliasTagDef {
int m = F<int>::S().g();
int n = F<int>::U().g();
}
+
+namespace rdar10397846 {
+ template<int I> struct A
+ {
+ struct B
+ {
+ struct C { C() { int *ptr = I; } }; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+ };
+ };
+
+ template<int N> void foo()
+ {
+ class A<N>::B::C X; // expected-note{{in instantiation of member function}}
+ int A<N+1>::B::C::*member = 0;
+ }
+
+ void bar()
+ {
+ foo<0>();
+ foo<1>(); // expected-note{{in instantiation of function template}}
+ }
+}
diff --git a/test/SemaTemplate/instantiate-self.cpp b/test/SemaTemplate/instantiate-self.cpp
new file mode 100644
index 000000000000..cfe902509f7f
--- /dev/null
+++ b/test/SemaTemplate/instantiate-self.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// Check that we deal with cases where the instantiation of a class template
+// recursively requires the instantiation of the same template.
+namespace test1 {
+ template<typename T> struct A {
+ struct B { // expected-note {{not complete until the closing '}'}}
+ B b; // expected-error {{has incomplete type 'test1::A<int>::B'}}
+ };
+ B b; // expected-note {{in instantiation of}}
+ };
+ A<int> a; // expected-note {{in instantiation of}}
+}
+
+namespace test2 {
+ template<typename T> struct A {
+ struct B {
+ struct C {};
+ char c[1 + C()]; // expected-error {{invalid operands to binary expression}}
+ friend constexpr int operator+(int, C) { return 4; }
+ };
+ B b; // expected-note {{in instantiation of}}
+ };
+ A<int> a; // expected-note {{in instantiation of}}
+}
+
+namespace test3 {
+ // PR12317
+ template<typename T> struct A {
+ struct B {
+ enum { Val = 1 };
+ char c[1 + Val]; // ok
+ };
+ B b;
+ };
+ A<int> a;
+}
+
+namespace test4 {
+ template<typename T> struct M { typedef int type; };
+ template<typename T> struct A {
+ struct B { // expected-note {{not complete until the closing '}'}}
+ int k[typename A<typename M<T>::type>::B().k[0] + 1]; // expected-error {{incomplete type}}
+ };
+ B b; // expected-note {{in instantiation of}}
+ };
+ A<int> a; // expected-note {{in instantiation of}}
+}
+
+// FIXME: PR12298: Recursive constexpr function template instantiation leads to
+// stack overflow.
+#if 0
+namespace test5 {
+ template<typename T> struct A {
+ constexpr T f(T k) { return g(k); }
+ constexpr T g(T k) {
+ return k ? f(k-1)+1 : 0;
+ }
+ };
+ // This should be accepted.
+ constexpr int x = A<int>().f(5);
+}
+
+namespace test6 {
+ template<typename T> constexpr T f(T);
+ template<typename T> constexpr T g(T t) {
+ typedef int arr[f(T())];
+ return t;
+ }
+ template<typename T> constexpr T f(T t) {
+ typedef int arr[g(T())];
+ return t;
+ }
+ // This should be ill-formed.
+ int n = f(0);
+}
+
+namespace test7 {
+ template<typename T> constexpr T g(T t) {
+ return t;
+ }
+ template<typename T> constexpr T f(T t) {
+ typedef int arr[g(T())];
+ return t;
+ }
+ // This should be accepted.
+ int n = f(0);
+}
+#endif
diff --git a/test/SemaTemplate/instantiate-sizeof.cpp b/test/SemaTemplate/instantiate-sizeof.cpp
new file mode 100644
index 000000000000..00d63d0c2fe5
--- /dev/null
+++ b/test/SemaTemplate/instantiate-sizeof.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// Make sure we handle contexts correctly with sizeof
+template<typename T> void f(T n) {
+ int buffer[n];
+ [] { int x = sizeof(sizeof(buffer)); }();
+}
+int main() {
+ f<int>(1);
+}
diff --git a/test/SemaTemplate/instantiate-static-var.cpp b/test/SemaTemplate/instantiate-static-var.cpp
index d2b0459ccc58..f309f29eafab 100644
--- a/test/SemaTemplate/instantiate-static-var.cpp
+++ b/test/SemaTemplate/instantiate-static-var.cpp
@@ -2,7 +2,7 @@
template<typename T, T Divisor>
class X {
public:
- static const T value = 10 / Divisor; // expected-error{{in-class initializer is not a constant expression}}
+ static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}}
};
int array1[X<int, 2>::value == 5? 1 : -1];
@@ -114,4 +114,3 @@ namespace PR6449 {
template class X1<char>;
}
-
diff --git a/test/SemaTemplate/instantiate-typeof.cpp b/test/SemaTemplate/instantiate-typeof.cpp
new file mode 100644
index 000000000000..92873cb4b0b6
--- /dev/null
+++ b/test/SemaTemplate/instantiate-typeof.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// Make sure we correctly treat __typeof as potentially-evaluated when appropriate
+template<typename T> void f(T n) {
+ int buffer[n]; // expected-note {{declared here}}
+ [] { __typeof(buffer) x; }(); // expected-error {{variable 'buffer' with variably modified type cannot be captured in a lambda expression}}
+}
+int main() {
+ f<int>(1); // expected-note {{in instantiation}}
+}
diff --git a/test/SemaTemplate/instantiation-depth.cpp b/test/SemaTemplate/instantiation-depth.cpp
index a2b9d2eb1513..8e1b80368d18 100644
--- a/test/SemaTemplate/instantiation-depth.cpp
+++ b/test/SemaTemplate/instantiation-depth.cpp
@@ -1,10 +1,12 @@
// RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 %s
+// RUN: %clang -fsyntax-only -Xclang -verify -ftemplate-depth-5 -ftemplate-backtrace-limit=4 %s
+// RUN: %clang -fsyntax-only -Xclang -verify -ftemplate-depth=5 -ftemplate-backtrace-limit=4 %s
template<typename T> struct X : X<T*> { }; \
// expected-error{{recursive template instantiation exceeded maximum depth of 5}} \
// expected-note 3 {{instantiation of template class}} \
// expected-note {{skipping 2 contexts in backtrace}} \
-// expected-note {{use -ftemplate-depth-N to increase recursive template instantiation depth}}
+// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
void test() {
(void)sizeof(X<int>); // expected-note {{instantiation of template class}}
diff --git a/test/SemaTemplate/instantiation-order.cpp b/test/SemaTemplate/instantiation-order.cpp
new file mode 100644
index 000000000000..e058a5bc1873
--- /dev/null
+++ b/test/SemaTemplate/instantiation-order.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// From core issue 1227.
+
+template <class T> struct A { using X = typename T::X; }; // expected-error {{no members}}
+template <class T> typename T::X f(typename A<T>::X);
+template <class T> void f(...) {}
+template <class T> auto g(typename A<T>::X) -> typename T::X; // expected-note {{here}} expected-note {{substituting}}
+template <class T> void g(...) {}
+
+void h()
+{
+ f<int>(0); // ok, SFINAE in return type
+ g<int>(0); // not ok, substitution inside A<int> is a hard error
+}
diff --git a/test/SemaTemplate/member-access-ambig.cpp b/test/SemaTemplate/member-access-ambig.cpp
index bf190435ecd5..f8a01d5fff2a 100644
--- a/test/SemaTemplate/member-access-ambig.cpp
+++ b/test/SemaTemplate/member-access-ambig.cpp
@@ -33,3 +33,13 @@ void X::g()
// expected-error{{expected '(' for function-style cast}} \
// expected-error{{expected expression}}
}
+
+namespace PR11134 {
+ template<typename Derived> class A;
+ template<typename Derived> class B : A<Derived> {
+ typedef A<Derived> Base;
+ using Base::member;
+ int member;
+ };
+}
+
diff --git a/test/SemaTemplate/member-template-access-expr.cpp b/test/SemaTemplate/member-template-access-expr.cpp
index dbd27c456c51..c95b57d4b4fd 100644
--- a/test/SemaTemplate/member-template-access-expr.cpp
+++ b/test/SemaTemplate/member-template-access-expr.cpp
@@ -60,7 +60,7 @@ struct X1 {
void test_X1(X1 x1) {
float *fp1 = x1.f1<>(17);
- float *fp2 = x1.f1<int>(3.14);
+ float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
int *ip1 = x1.f1(17);
float *ip2 = x1.f1(3.14);
diff --git a/test/SemaTemplate/ms-if-exists.cpp b/test/SemaTemplate/ms-if-exists.cpp
new file mode 100644
index 000000000000..04f4a6362361
--- /dev/null
+++ b/test/SemaTemplate/ms-if-exists.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fms-extensions -std=c++11 %s -verify
+
+struct Nontemplate {
+ typedef int type;
+};
+
+template<typename T>
+struct X {
+ __if_exists(Nontemplate::type) {
+ typedef Nontemplate::type type;
+ }
+
+ __if_exists(Nontemplate::value) {
+ typedef Nontemplate::value type2;
+ }
+
+ __if_not_exists(Nontemplate::value) {
+ typedef int type3;
+ }
+
+ __if_exists(T::X) { // expected-warning{{dependent __if_exists declarations are ignored}}
+ typedef T::X type4;
+ }
+};
+
+X<int>::type i1;
+X<int>::type2 i2; // expected-error{{no type named 'type2' in 'X<int>'}}
+X<int>::type3 i3;
+X<int>::type4 i4; // expected-error{{no type named 'type4' in 'X<int>'}}
+
+struct HasFoo {
+ void foo();
+};
+struct HasBar {
+ void bar(int);
+ void bar(float);
+};
+
+template<typename T>
+void f(T t) {
+ __if_exists(T::foo) {
+ { }
+ t.foo();
+ }
+
+ __if_not_exists(T::bar) {
+ int *i = t; // expected-error{{no viable conversion from 'HasFoo' to 'int *'}}
+ { }
+ }
+
+ int array2[] = {
+ 0,
+ __if_exists(T::bar) {2, }// expected-warning{{dependent __if_exists declarations are ignored}}
+ 3
+ };
+}
+
+template void f(HasFoo); // expected-note{{in instantiation of function template specialization 'f<HasFoo>' requested here}}
+template void f(HasBar);
+
+template<typename T, typename ...Ts>
+void g(T, Ts...) {
+ __if_exists(T::operator Ts) { // expected-error{{__if_exists name contains unexpanded parameter pack 'Ts'}}
+ }
+
+ __if_not_exists(Ts::operator T) { // expected-error{{__if_not_exists name contains unexpanded parameter pack 'Ts'}}
+ }
+}
diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
index 910fa37e80d8..2c422dc7e3f7 100644
--- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
template <class T>
@@ -28,4 +28,118 @@ void test()
b.z(3);
}
+namespace lookup_dependent_bases_id_expr {
+template<class T> class A {
+public:
+ int var;
+};
+
+
+template<class T>
+class B : public A<T> {
+public:
+ void f() {
+ var = 3;
+ }
+};
+
+template class B<int>;
+
+}
+
+
+
+namespace lookup_dependent_base_class_static_function {
+
+template <class T>
+class A {
+public:
+ static void static_func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
+ void func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
+};
+
+
+template <class T>
+class B : public A<T> {
+public:
+ static void z2(){
+ static_func(); // expected-warning {{use of identifier 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ func(); // expected-warning {{use of identifier 'func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
+ }
+};
+template class B<int>; // expected-note {{requested here}}
+
+}
+
+
+
+namespace lookup_dependent_base_class_default_argument {
+
+template<class T>
+class A {
+public:
+ static int f1(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
+ int f2(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
+};
+
+template<class T>
+class B : public A<T> {
+public:
+ void g1(int p = f1());// expected-warning {{use of identifier 'f1' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ void g2(int p = f2());// expected-warning {{use of identifier 'f2' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
+};
+
+void foo()
+{
+ B<int> b;
+ b.g1(); // expected-note {{required here}}
+ b.g2(); // expected-note {{required here}}
+}
+
+}
+
+
+namespace lookup_dependent_base_class_friend {
+
+template <class T>
+class B {
+public:
+ static void g(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
+};
+
+template <class T>
+class A : public B<T> {
+public:
+ friend void foo(A<T> p){
+ g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ }
+};
+
+int main2()
+{
+ A<int> a;
+ foo(a); // expected-note {{requested here}}
+}
+
+}
+
+
+namespace lookup_dependent_base_no_typo_correction {
+
+class C {
+public:
+ int m_hWnd;
+};
+
+template <class T>
+class A : public T {
+public:
+ void f(int hWnd) {
+ m_hWnd = 1;
+ }
+};
+
+template class A<C>;
+
+}
diff --git a/test/SemaTemplate/nested-incomplete-class.cpp b/test/SemaTemplate/nested-incomplete-class.cpp
new file mode 100644
index 000000000000..a4bfccb8d279
--- /dev/null
+++ b/test/SemaTemplate/nested-incomplete-class.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template <typename T>
+struct foo {
+ struct bar;
+
+ bar fn() {
+ // Should not get errors about bar being incomplete here.
+ bar b = bar(1, 2);
+ return b;
+ }
+};
+
+template <typename T>
+struct foo<T>::bar {
+ bar(int, int);
+};
+
+void fn() {
+ foo<int>().fn();
+}
diff --git a/test/SemaTemplate/nested-template.cpp b/test/SemaTemplate/nested-template.cpp
index ab647aa22675..7849bae4d571 100644
--- a/test/SemaTemplate/nested-template.cpp
+++ b/test/SemaTemplate/nested-template.cpp
@@ -142,3 +142,16 @@ namespace PR10896 {
f.foo();
}
}
+
+namespace PR10924 {
+ template< class Topology, class ctype >
+ struct ReferenceElement
+ {
+ };
+
+ template< class Topology, class ctype >
+ template< int codim >
+ class ReferenceElement< Topology, ctype > :: BaryCenterArray // expected-error{{out-of-line definition of 'BaryCenterArray' does not match any declaration in 'ReferenceElement<Topology, ctype>'}}
+ {
+ };
+}
diff --git a/test/SemaTemplate/pragma-ms_struct.cpp b/test/SemaTemplate/pragma-ms_struct.cpp
new file mode 100644
index 000000000000..f04dc5ccae45
--- /dev/null
+++ b/test/SemaTemplate/pragma-ms_struct.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-apple-osx10.7.0 %s
+
+#pragma ms_struct on
+
+// <rdar://problem/10791194>
+template<int x> struct foo {
+ long long a;
+ int b;
+};
+extern int arr[sizeof(foo<0>) == 16 ? 1 : -1];
diff --git a/test/SemaTemplate/qualified-id.cpp b/test/SemaTemplate/qualified-id.cpp
index 29eab89d84f5..64dff1ce2353 100644
--- a/test/SemaTemplate/qualified-id.cpp
+++ b/test/SemaTemplate/qualified-id.cpp
@@ -45,3 +45,12 @@ namespace PR6063 {
detail::f(a, b);
}
}
+
+namespace PR12291 {
+ template <typename T>
+ class Outer2 {
+ template <typename V>
+ template <typename W>
+ class Outer2<V>::Inner; // expected-error{{nested name specifier 'Outer2<V>::' for declaration does not refer into a class, class template or class template partial specialization}}
+ };
+}
diff --git a/test/SemaTemplate/resolve-single-template-id.cpp b/test/SemaTemplate/resolve-single-template-id.cpp
index b9833d8609ef..0c9bacca3edd 100644
--- a/test/SemaTemplate/resolve-single-template-id.cpp
+++ b/test/SemaTemplate/resolve-single-template-id.cpp
@@ -41,7 +41,7 @@ int main()
*oneT<int>; // expected-warning {{expression result unused}}
*two; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error {{indirection requires pointer operand}}
*twoT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
- !oneT<int>; // expected-warning {{expression result unused}}
+ !oneT<int>; // expected-warning {{expression result unused}} expected-warning {{address of function 'oneT<int>' will always evaluate to 'true'}} expected-note {{prefix with the address-of operator to silence this warning}}
+oneT<int>; // expected-warning {{expression result unused}}
-oneT<int>; //expected-error {{invalid argument type}}
oneT<int> == 0; // expected-warning {{equality comparison result unused}} \
@@ -53,7 +53,7 @@ int main()
int i = (int) (false ? (void (*)(int))twoT<int> : oneT<int>); //expected-error {{incompatible operand}}
(twoT<int>) == oneT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} {{cannot resolve overloaded function 'twoT' from context}}
- bool b = oneT<int>;
+ bool b = oneT<int>; // expected-warning {{address of function 'oneT<int>' will always evaluate to 'true'}} expected-note {{prefix with the address-of operator to silence this warning}}
void (*p)() = oneT<int>;
test<oneT<int> > ti;
void (*u)(int) = oneT<int>;
diff --git a/test/SemaTemplate/temp_arg_template.cpp b/test/SemaTemplate/temp_arg_template.cpp
index 9c34089e61f7..c9ce1b694363 100644
--- a/test/SemaTemplate/temp_arg_template.cpp
+++ b/test/SemaTemplate/temp_arg_template.cpp
@@ -54,3 +54,9 @@ namespace N {
void f0( Y<int,1> y){ 1 << y; } // expected-note{{in instantiation of function template specialization 'N::operator<<<Y, int, 1>' requested here}}
}
+
+// PR12179
+template <typename Primitive, template <Primitive...> class F> // expected-warning {{variadic templates are a C++11 extension}}
+struct unbox_args {
+ typedef typename Primitive::template call<F> x;
+};
diff --git a/test/SemaTemplate/temp_class_spec_neg.cpp b/test/SemaTemplate/temp_class_spec_neg.cpp
index 6b129a5369fb..be5fbb154ea8 100644
--- a/test/SemaTemplate/temp_class_spec_neg.cpp
+++ b/test/SemaTemplate/temp_class_spec_neg.cpp
@@ -9,7 +9,7 @@ namespace N {
}
template<typename T>
-struct N::M::A<T*> { }; // expected-warning{{originally}}
+struct N::M::A<T*> { }; // expected-warning{{C++11 extension}}
// C++ [temp.class.spec]p9
// bullet 1
diff --git a/test/SemaTemplate/temp_explicit.cpp b/test/SemaTemplate/temp_explicit.cpp
index 76244c25e824..80c90d0cfcd2 100644
--- a/test/SemaTemplate/temp_explicit.cpp
+++ b/test/SemaTemplate/temp_explicit.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++0x-compat %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat %s
//
// Tests explicit instantiation of templates.
template<typename T, typename U = T> class X0 { };
@@ -80,7 +80,7 @@ struct X5 {
void f(T&);
};
- struct Inner2 {
+ struct Inner2 { // expected-note {{here}}
struct VeryInner {
void g(T*); // expected-error 2{{pointer to a reference}}
};
@@ -98,7 +98,7 @@ void f4(X5<float&>::Inner2);
template struct X5<float&>::Inner2; // expected-note{{instantiation}}
namespace N3 {
- template struct N2::X5<int>::Inner2;
+ template struct N2::X5<int>::Inner2; // expected-warning {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}}
}
struct X6 {
@@ -147,5 +147,5 @@ namespace N2 {
template struct X7<double>; // expected-warning{{must occur in namespace}}
- template struct X9<float>; // expected-warning{{must occur in the global}}
+ template struct X9<float>; // expected-warning{{must occur at global scope}}
}
diff --git a/test/SemaTemplate/temp_explicit_cxx0x.cpp b/test/SemaTemplate/temp_explicit_cxx0x.cpp
index 9d6dc80b5b0a..e37fcd7c6a5d 100644
--- a/test/SemaTemplate/temp_explicit_cxx0x.cpp
+++ b/test/SemaTemplate/temp_explicit_cxx0x.cpp
@@ -18,7 +18,7 @@ template struct ::N1::Inner::X1<float>;
namespace N2 {
using namespace N1;
- template struct X0<double>; // expected-error{{not in a namespace enclosing}}
+ template struct X0<double>; // expected-error{{must occur in namespace 'N1'}}
template struct X2<float>; // expected-error{{at global scope}}
}
diff --git a/test/SemaTemplate/template-id-expr.cpp b/test/SemaTemplate/template-id-expr.cpp
index de8d7f6c91a4..4416f92723ad 100644
--- a/test/SemaTemplate/template-id-expr.cpp
+++ b/test/SemaTemplate/template-id-expr.cpp
@@ -82,3 +82,17 @@ struct Y0 {
x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
}
};
+
+struct A {
+ template<int I>
+ struct B {
+ static void b1();
+ };
+};
+
+template<int I>
+void f5() {
+ A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}}
+}
+
+template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}}
diff --git a/test/SemaTemplate/template-id-printing.cpp b/test/SemaTemplate/template-id-printing.cpp
index fcd4974a7611..047589b1ce43 100644
--- a/test/SemaTemplate/template-id-printing.cpp
+++ b/test/SemaTemplate/template-id-printing.cpp
@@ -11,3 +11,131 @@ void g() {
// CHECK: N::f<double>
void (*fp)(int) = N::f<double>;
}
+
+
+// (NNS qualified) DeclRefExpr.
+namespace DRE {
+
+template <typename T>
+void foo();
+
+void test() {
+ // CHECK: DRE::foo<int>;
+ DRE::foo<int>;
+ // CHECK: DRE::template foo<int>;
+ DRE::template foo<int>;
+ // CHECK: DRE::foo<int>();
+ DRE::foo<int>();
+ // CHECK: DRE::template foo<int>();
+ DRE::template foo<int>();
+}
+
+} // namespace DRE
+
+
+// MemberExpr.
+namespace ME {
+
+struct S {
+ template <typename T>
+ void mem();
+};
+
+void test() {
+ S s;
+ // CHECK: s.mem<int>();
+ s.mem<int>();
+ // CHECK: s.template mem<int>();
+ s.template mem<int>();
+}
+
+} // namespace ME
+
+
+// UnresolvedLookupExpr.
+namespace ULE {
+
+template <typename T>
+int foo();
+
+template <typename T>
+void test() {
+ // CHECK: ULE::foo<T>;
+ ULE::foo<T>;
+ // CHECK: ULE::template foo<T>;
+ ULE::template foo<T>;
+}
+
+} // namespace ULE
+
+
+// UnresolvedMemberExpr.
+namespace UME {
+
+struct S {
+ template <typename T>
+ void mem();
+};
+
+template <typename U>
+void test() {
+ S s;
+ // CHECK: s.mem<U>();
+ s.mem<U>();
+ // CHECK: s.template mem<U>();
+ s.template mem<U>();
+}
+
+} // namespace UME
+
+
+// DependentScopeDeclRefExpr.
+namespace DSDRE {
+
+template <typename T>
+struct S;
+
+template <typename T>
+void test() {
+ // CHECK: S<T>::foo;
+ S<T>::foo;
+ // CHECK: S<T>::template foo;
+ S<T>::template foo;
+ // CHECK: S<T>::template foo<>;
+ S<T>::template foo<>;
+ // CHECK: S<T>::template foo<T>;
+ S<T>::template foo<T>;
+}
+
+} // namespace DSDRE
+
+
+// DependentScopeMemberExpr.
+namespace DSME {
+
+template <typename T>
+struct S;
+
+template <typename T>
+void test() {
+ S<T> s;
+ // CHECK: s.foo;
+ s.foo;
+ // CHECK: s.template foo;
+ s.template foo;
+ // CHECK: s.template foo<>;
+ s.template foo<>;
+ // CHECK: s.template foo<T>;
+ s.template foo<T>;
+}
+
+} // namespace DSME
+
+namespace DSDRE_withImplicitTemplateArgs {
+
+template <typename T> void foo() {
+ // CHECK: T::template bar();
+ T::template bar();
+}
+
+} // namespace DSDRE_withImplicitTemplateArgs