aboutsummaryrefslogtreecommitdiff
path: root/test/CXX/temp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
committerDimitry Andric <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
commitbfef399519ca9b8a4b4c6b563253bad7e0eeffe0 (patch)
treedf8df0b0067b381eab470a3b8f28d14a552a6340 /test/CXX/temp
parent6a0372513edbc473b538d2f724efac50405d6fef (diff)
downloadsrc-bfef399519ca9b8a4b4c6b563253bad7e0eeffe0.tar.gz
src-bfef399519ca9b8a4b4c6b563253bad7e0eeffe0.zip
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):vendor/clang/clang-release_34-r197841
Notes
Notes: svn path=/vendor/clang/dist/; revision=259701 svn path=/vendor/clang/clang-release_34-r197841/; revision=259703; tag=vendor/clang/clang-release_34-r197841
Diffstat (limited to 'test/CXX/temp')
-rw-r--r--test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp4
-rw-r--r--test/CXX/temp/temp.decls/temp.alias/p3.cpp4
-rw-r--r--test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp35
-rw-r--r--test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp6
-rw-r--r--test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp2
-rw-r--r--test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp7
-rw-r--r--test/CXX/temp/temp.decls/temp.friend/p4.cpp17
-rw-r--r--test/CXX/temp/temp.decls/temp.friend/p5.cpp8
-rw-r--r--test/CXX/temp/temp.decls/temp.mem/p2.cpp12
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p2.cpp2
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p5.cpp12
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp203
-rw-r--r--test/CXX/temp/temp.param/p5.cpp9
-rw-r--r--test/CXX/temp/temp.res/temp.local/p6.cpp69
-rw-r--r--test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp37
-rw-r--r--test/CXX/temp/temp.spec/no-body.cpp63
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp2
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp2
-rw-r--r--test/CXX/temp/temp.spec/temp.inst/p1.cpp11
19 files changed, 482 insertions, 23 deletions
diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
index c4db0027052c..3f70ca7c81ab 100644
--- a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
+++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
@@ -27,7 +27,7 @@ namespace non_type_tmpl_param {
// omitted if the name refers to a function or array and shall be omitted
// if the corresopnding template-parameter is a reference; or
namespace addr_of_obj_or_func {
- template <int* p> struct X0 { }; // expected-note 4{{here}}
+ template <int* p> struct X0 { }; // expected-note 5{{here}}
template <int (*fp)(int)> struct X1 { };
template <int &p> struct X2 { }; // expected-note 4{{here}}
template <const int &p> struct X2k { }; // expected-note {{here}}
@@ -40,6 +40,7 @@ namespace addr_of_obj_or_func {
__thread int ti = 100; // expected-note 2{{here}}
static int f_internal(int); // expected-note 4{{here}}
template <typename T> T f_tmpl(T t);
+ struct S { union { int NonStaticMember; }; };
void test() {
X0<i> x0a; // expected-error {{must have its address taken}}
@@ -78,6 +79,7 @@ namespace addr_of_obj_or_func {
X0<&n> x0_no_linkage; // expected-error {{non-type template argument refers to object 'n' that does not have linkage}}
struct Local { static int f() {} }; // expected-note {{here}}
X1<&Local::f> x1_no_linkage; // expected-error {{non-type template argument refers to function 'f' that does not have linkage}}
+ X0<&S::NonStaticMember> x0_non_static; // expected-error {{non-static data member}}
}
}
diff --git a/test/CXX/temp/temp.decls/temp.alias/p3.cpp b/test/CXX/temp/temp.decls/temp.alias/p3.cpp
index afd9b4b0de30..2d46502e1d9b 100644
--- a/test/CXX/temp/temp.decls/temp.alias/p3.cpp
+++ b/test/CXX/temp/temp.decls/temp.alias/p3.cpp
@@ -9,5 +9,9 @@ template<class T> struct A {
B<short> b;
template<typename T> using U = int;
+
+template<typename ...T> void f(U<T> ...xs);
+void g() { f<void,void,void>(1, 2, 3); }
+
// FIXME: This is illegal, but probably only because CWG1044 missed this paragraph.
template<typename T> using U = U<T>;
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
new file mode 100644
index 000000000000..a49db5166a45
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -std=c++1y -fsyntax-only -verify %s
+
+// -- The argument list of the specialization shall not be identical
+// to the implicit argument list of the primary template.
+
+template<typename T, int N, template<typename> class X> int v1;
+template<typename T, int N, template<typename> class X> int v1<T, N, X>;
+// expected-error@-1{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template<typename...T> int v2;
+template<typename...T> int v2<T...>;
+// expected-error@-1{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template<int...N> int v3;
+template<int...N> int v3<N...>;
+// expected-error@-1{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template<template<typename> class...X> int v4;
+template<template<typename> class...X> int v4<X...>;
+// expected-error@-1{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template<typename Outer> struct X {
+ template<typename Inner> static int y;
+ template<typename Inner> static int y<Outer>; // expected-warning {{can not be deduced}} expected-note {{'Inner'}}
+ template<typename Inner> static int y<Inner>; // expected-error {{does not specialize}}
+};
+template<typename Outer> template<typename Inner> int X<Outer>::y<Outer>; // expected-warning {{can not be deduced}} expected-note {{'Inner'}}
+template<typename Outer> template<typename Inner> int X<Outer>::y<Inner>; // expected-error {{does not specialize}}
+
+// FIXME: Merging this with the above class causes an assertion failure when
+// instantiating one of the bogus partial specializations.
+template<typename Outer> struct Y {
+ template<typename Inner> static int y;
+};
+template<> template<typename Inner> int Y<int>::y<Inner>; // expected-error {{does not specialize}}
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
index f8cc00947480..2884be146c7c 100644
--- a/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
@@ -12,7 +12,7 @@ A<int> a;
A<int>::E a0 = A<int>().v;
int n = A<int>::E::e1; // expected-error {{implicit instantiation of undefined member}}
-template<typename T> enum A<T>::E : T { e1, e2 };
+template<typename T> enum A<T>::E : T { e1, e2 }; // expected-note 2 {{declared here}}
// FIXME: Now that A<T>::E is defined, we are supposed to inject its enumerators
// into the already-instantiated class A<T>. This seems like a really bad idea,
@@ -20,7 +20,7 @@ template<typename T> enum A<T>::E : T { e1, e2 };
//
// Either do as the standard says, or only include enumerators lexically defined
// within the class in its scope.
-A<int>::E a1 = A<int>::e1; // expected-error {{no member named 'e1' in 'A<int>'}}
+A<int>::E a1 = A<int>::e1; // expected-error {{no member named 'e1' in 'A<int>'; did you mean simply 'e1'?}}
A<char>::E a2 = A<char>::e2;
@@ -94,7 +94,7 @@ D<int>::E d1 = D<int>::E::e1; // expected-error {{incomplete type 'D<int>::E'}}
template<> enum class D<int>::E { e2 };
D<int>::E d2 = D<int>::E::e2;
D<char>::E d3 = D<char>::E::e1; // expected-note {{first required here}}
-D<char>::E d4 = D<char>::E::e2; // expected-error {{no member named 'e2'}}
+D<char>::E d4 = D<char>::E::e2; // expected-error {{no member named 'e2' in 'D<char>::E'; did you mean simply 'e2'?}}
template<> enum class D<char>::E { e3 }; // expected-error {{explicit specialization of 'E' after instantiation}}
template<> enum class D<short>::E;
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp b/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
index 2eae1125c0db..8a3168e5f806 100644
--- a/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
@@ -23,4 +23,4 @@ X2& get_X2() {
return X0<X2>::value; // expected-note{{instantiation}}
}
-template<typename T> T x; // expected-error{{variable 'x' declared as a template}}
+template<typename T> T x; // expected-warning{{variable templates are a C++1y extension}}
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
index 6d22f8809365..60c60cb0b28d 100644
--- a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
+++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
@@ -43,3 +43,10 @@ namespace OrderWithStaticMember {
a.g(p);
}
}
+
+namespace PR17075 {
+ template <typename T> struct V {};
+ struct S { template<typename T> S &operator>>(T &t) = delete; };
+ template<typename T> S &operator>>(S &s, V<T> &v);
+ void f(S s, V<int> v) { s >> v; }
+}
diff --git a/test/CXX/temp/temp.decls/temp.friend/p4.cpp b/test/CXX/temp/temp.decls/temp.friend/p4.cpp
index e036cef32b28..8571a141201b 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p4.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p4.cpp
@@ -26,3 +26,20 @@ void g() {
X2<float> xf;
f(xf);
}
+
+template<typename T>
+struct X3 {
+ operator int();
+
+ friend void h(int x);
+};
+
+int array2[sizeof(X3<int>)];
+int array3[sizeof(X3<float>)];
+
+void i() {
+ X3<int> xi;
+ h(xi);
+ X3<float> xf;
+ h(xf);
+}
diff --git a/test/CXX/temp/temp.decls/temp.friend/p5.cpp b/test/CXX/temp/temp.decls/temp.friend/p5.cpp
index 4b899e4e5211..b26abb64f838 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p5.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p5.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
namespace test0 {
template <class T> class A {
@@ -7,7 +6,8 @@ namespace test0 {
};
class B {
- template <class T> friend class A<T>::Member;
+ template <class T> friend class A<T>::Member; // expected-warning {{not supported}}
+ int n;
};
A<int> a;
@@ -68,7 +68,7 @@ namespace test3 {
template <class U> class C {
int i;
- template <class T> friend struct A<T>::Inner;
+ template <class T> friend struct A<T>::Inner; // expected-warning {{not supported}}
};
template <class T> int A<T>::Inner::foo() {
@@ -96,7 +96,7 @@ namespace test4 {
namespace test5 {
template<template <class> class T> struct A {
- template<template <class> class T> friend void A<T>::foo();
+ template<template <class> class U> friend void A<U>::foo();
};
template <class> struct B {};
diff --git a/test/CXX/temp/temp.decls/temp.mem/p2.cpp b/test/CXX/temp/temp.decls/temp.mem/p2.cpp
new file mode 100644
index 000000000000..c24d5a9b50de
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.mem/p2.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <typename>
+void quux();
+
+void fun() {
+ struct foo {
+ template <typename> struct bar {}; // expected-error{{templates cannot be declared inside of a local class}}
+ template <typename> void baz() {} // expected-error{{templates cannot be declared inside of a local class}}
+ template <typename> void qux(); // expected-error{{templates cannot be declared inside of a local class}}
+ };
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p2.cpp b/test/CXX/temp/temp.decls/temp.variadic/p2.cpp
index ce19582c2282..e7a62366a9be 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/p2.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/p2.cpp
@@ -12,7 +12,7 @@ void test() {
template<typename Head, typename ...Tail>
void recurse_until_fail(const Head &, const Tail &...tail) { // expected-note{{candidate function template not viable: requires at least 1 argument, but 0 were provided}}
recurse_until_fail(tail...); // expected-error{{no matching function for call to 'recurse_until_fail'}} \
- // expected-note{{in instantiation of function template specialization 'recurse_until_fail<char [7], >' requested here}} \
+ // expected-note{{in instantiation of function template specialization 'recurse_until_fail<char [7]>' requested here}} \
// expected-note{{in instantiation of function template specialization 'recurse_until_fail<double, char [7]>' requested here}}
}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
index 945379872f78..3681d7757e94 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -165,6 +165,7 @@ template<typename T, typename... Types>
struct alignas(Types) TestUnexpandedDecls : T{ // expected-error{{expression contains unexpanded parameter pack 'Types'}}
void member_function(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
void member_function () throw(Types); // expected-error{{exception type contains unexpanded parameter pack 'Types'}}
+ void member_function2() noexcept(Types()); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
operator Types() const; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
Types data_member; // expected-error{{data member type contains unexpanded parameter pack 'Types'}}
static Types static_data_member; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
@@ -410,3 +411,14 @@ namespace WorkingPaperExample {
f(h(args ...) + args ...);
}
}
+
+namespace PR16303 {
+ template<int> struct A { A(int); };
+ template<int...N> struct B {
+ template<int...M> struct C : A<N>... {
+ C() : A<N>(M)... {} // expected-error{{pack expansion contains parameter packs 'N' and 'M' that have different lengths (2 vs. 3)}} expected-error{{pack expansion contains parameter packs 'N' and 'M' that have different lengths (4 vs. 3)}}
+ };
+ };
+ B<1,2>::C<4,5,6> c1; // expected-note{{in instantiation of}}
+ B<1,2,3,4>::C<4,5,6> c2; // expected-note{{in instantiation of}}
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp b/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp
new file mode 100644
index 000000000000..4960a2bac20a
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp
@@ -0,0 +1,203 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+namespace pr12262 {
+
+template<typename T, typename... Ts>
+void abc1(int (*xxx)[sizeof ... (Ts) + 1]);
+
+void qq1 () {
+ abc1<int>(0);
+ abc1<int,double>(0);
+}
+
+
+template <unsigned N> class array {};
+
+
+template<typename T, typename... Types>
+array<sizeof...(Types)> make_array1(Types&&... args);
+
+void qq2 () {
+ array<1> arr = make_array1<int>(1);
+ array<3> arr2 = make_array1<int>(1,array<5>(),0.1);
+}
+
+
+template<typename T, typename... Types>
+int make_array(array<sizeof...(Types)>&, Types... args);
+
+void qq3 () {
+ array<1> a1;
+ int aa1 = make_array<int>(a1,1);
+ array<2> a2;
+ int aa2 = make_array<int>(a2, 0L, "abc");
+}
+
+
+template<typename ... Ts>
+struct AAA {
+ template<typename T, typename... Types>
+ static array<sizeof...(Types)> make_array(Types ... args);
+};
+
+void qq4 () {
+ array<2> arr2 = AAA<int, int>::make_array<int>(1,2);
+}
+
+}
+
+
+namespace pr12439 {
+
+template<class... Members>
+struct X {
+ template<int Idx>
+ using get_t = decltype(sizeof...(Members));
+
+ template<int i>
+ get_t<i> get();
+};
+
+template<class... Members>
+template<int i>
+X<Members...>::get_t<i> X<Members...>::get()
+{
+ return 0;
+}
+
+}
+
+
+namespace pr13272 {
+
+template<bool B, class T = void>
+struct enable_if { };
+
+template<class T> struct enable_if<true, T> {
+ typedef T type;
+};
+
+class Exception {};
+
+template<class Ex, typename... Args>
+void cxx_throw(typename enable_if<(sizeof...(Args) > 0), const char *>::type fmt, Args&&... args) {
+ return;
+}
+
+void test() {
+ cxx_throw<Exception>("Youpi",1);
+}
+
+}
+
+
+namespace pr13817 {
+
+template <unsigned>
+struct zod;
+
+template <>
+struct zod<1> {};
+
+template <typename T, typename ... Ts>
+zod<sizeof...(Ts)> make_zod(Ts ...) {
+ return zod<sizeof...(Ts)>();
+}
+
+int main(int argc, char *argv[])
+{
+ make_zod<int>(1);
+ return 0;
+}
+
+}
+
+
+namespace pr14273 {
+
+template<typename T, int i>
+struct myType
+{ };
+
+template<typename T, typename... Args>
+struct Counter
+{
+ static const int count = 1 + Counter<Args...>::count;
+};
+
+template<typename T>
+struct Counter<T>
+{
+ static const int count = 1;
+};
+
+template<typename Arg, typename... Args>
+myType<Arg, sizeof...(Args)>* make_array_with_type(const Args&... args)
+{
+ return 0;
+}
+
+void func(void)
+{
+ make_array_with_type<char>(1,2,3);
+}
+
+}
+
+
+namespace pr15112
+{
+ template<bool, typename _Tp = void>
+ struct enable_if
+ { };
+ template<typename _Tp>
+ struct enable_if<true,_Tp>
+ { typedef _Tp type; };
+
+ typedef __typeof__(sizeof(int)) size_t;
+
+ template <size_t n, typename T, typename... Args>
+ struct is_array_of { static const bool value = true; };
+
+ struct cpu { using value_type = void; };
+
+ template <size_t Order, typename T>
+ struct coords_alias { typedef T type; };
+
+ template <size_t Order, typename MemoryTag>
+ using coords = typename coords_alias<Order, MemoryTag>::type;
+
+ template <typename MemTag, typename... Args>
+ typename enable_if<is_array_of<sizeof...(Args), size_t, Args...>::value,
+ coords<sizeof...(Args), MemTag>>::type
+ mkcoords(Args... args);
+
+ auto c1 = mkcoords<cpu>(0ul, 0ul, 0ul);
+}
+
+
+namespace pr12699 {
+
+template<bool B>
+struct bool_constant
+{
+ static const bool value = B;
+};
+
+template<typename... A>
+struct F
+{
+ template<typename... B>
+ using SameSize = bool_constant<sizeof...(A) == sizeof...(B)>;
+
+ template<typename... B, typename = SameSize<B...>>
+ F(B...) { }
+};
+
+void func()
+{
+ F<int> f1(3);
+}
+
+}
diff --git a/test/CXX/temp/temp.param/p5.cpp b/test/CXX/temp/temp.param/p5.cpp
index 67efc4e48162..c25868267e49 100644
--- a/test/CXX/temp/temp.param/p5.cpp
+++ b/test/CXX/temp/temp.param/p5.cpp
@@ -1,14 +1,13 @@
// RUN: %clang_cc1 -verify %s -std=c++11
-// expected-no-diagnostics
template<const int I> struct S {
decltype(I) n;
- int &&r = I;
+ int &&r = I; // expected-warning 2{{binding reference member 'r' to a temporary value}} expected-note 2{{declared here}}
};
-S<5> s;
+S<5> s; // expected-note {{instantiation}}
template<typename T, T v> struct U {
decltype(v) n;
- int &&r = v;
+ int &&r = v; // expected-warning {{binding reference member 'r' to a temporary value}} expected-note {{declared here}}
};
-U<const int, 6> u;
+U<const int, 6> u; // expected-note {{instantiation}}
diff --git a/test/CXX/temp/temp.res/temp.local/p6.cpp b/test/CXX/temp/temp.res/temp.local/p6.cpp
new file mode 100644
index 000000000000..eccbb8993213
--- /dev/null
+++ b/test/CXX/temp/temp.res/temp.local/p6.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -verify %s -fcxx-exceptions -std=c++1y
+
+template<typename T, // expected-note {{declared here}}
+ typename T> struct X {}; // expected-error {{declaration of 'T' shadows template parameter}}
+
+template<typename T> struct Y { // expected-note 15{{declared here}}
+ template<typename T> struct A {}; // expected-error {{declaration of 'T' shadows template parameter}}
+
+ struct B {
+ template<typename> struct T {}; // FIXME: desired-error {{declaration of 'T' shadows template parameter}}
+ };
+ struct C {
+ template<typename> void T(); // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ struct D {
+ struct T {}; // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ struct E {
+ typedef int T; // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ struct F {
+ using T = int; // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ struct G {
+ int T; // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ struct H {
+ static int T; // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ struct I {
+ void T(); // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ struct J {
+ enum T { e }; // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ struct K {
+ enum E { T }; // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+
+ void a() {
+ extern int T; // expected-error {{declaration of 'T' shadows template parameter}}
+ }
+ void b() {
+ int T; // expected-error {{declaration of 'T' shadows template parameter}}
+ }
+ void c() {
+ try {}
+ catch (int T) {} // expected-error {{declaration of 'T' shadows template parameter}}
+ }
+ void d() {
+ void T(); // expected-error {{declaration of 'T' shadows template parameter}}
+ }
+
+ friend struct T; // expected-error {{declaration of 'T' shadows template parameter}}
+};
+
+template<typename T> // expected-note {{declared here}}
+void f(int T) {} // expected-error {{declaration of 'T' shadows template parameter}}
+
+// FIXME: These are ill-formed: a template-parameter shall not have the same name as the template name.
+namespace A {
+ template<typename T> struct T {};
+}
+namespace B {
+ template<typename T> void T() {}
+}
+namespace C {
+ template<typename T> int T;
+}
diff --git a/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp b/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
new file mode 100644
index 000000000000..93f8ff1697bf
--- /dev/null
+++ b/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 --std=c++1y -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: not %clang_cc1 --std=c++1y -x c++ -fixit %t -DFIXING
+// RUN: %clang_cc1 --std=c++1y -x c++ %t -DFIXING
+
+template<typename T>
+T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
+
+template int pi<int>;
+
+#ifndef FIXING
+template float pi<>; // expected-error {{too few template arguments for template 'pi'}}
+template double pi_var0; // expected-error {{explicit instantiation of 'pi_var0' does not refer to a function template, variable template, member function, member class, or static data member}}
+#endif
+
+// Should recover as if definition
+template double pi_var = 5; // expected-error {{variable cannot be defined in an explicit instantiation; if this declaration is meant to be a variable definition, remove the 'template' keyword}}
+#ifndef FIXING
+template<typename T>
+T pi0 = T(3.1415926535897932385); // expected-note {{previous definition is here}}
+
+template int pi0 = 10; // expected-error {{variable cannot be defined in an explicit instantiation; if this declaration is meant to be a variable definition, remove the 'template' keyword}} \
+ expected-error{{redefinition of 'pi0' as different kind of symbol}}
+#endif
+
+template<typename T>
+T pi1 = T(3.1415926535897932385);
+
+// Should recover as if specialization
+template float pi1<float> = 1.0; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}}
+#ifndef FIXING
+namespace expected_global {
+ template<> double pi1<double> = 1.5; // expected-error {{no variable template matches specialization}}
+ template int pi1<int> = 10; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \
+ expected-error {{no variable template matches specialization}}
+}
+#endif
diff --git a/test/CXX/temp/temp.spec/no-body.cpp b/test/CXX/temp/temp.spec/no-body.cpp
new file mode 100644
index 000000000000..a4d7914d9eb6
--- /dev/null
+++ b/test/CXX/temp/temp.spec/no-body.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: not %clang_cc1 -x c++ -fixit %t -DFIXING
+// RUN: %clang_cc1 -x c++ %t -DFIXING
+
+template<typename T> void f(T) { }
+template<typename T> void g(T) { }
+template<typename T> struct x { };
+template<typename T> struct y { }; // expected-note {{declared here}}
+
+namespace good {
+ template void f<int>(int);
+ template void g(int);
+ template struct x<int>;
+}
+
+namespace unsupported {
+#ifndef FIXING
+ template struct y; // expected-error {{elaborated type refers to a template}}
+#endif
+}
+
+template<typename T> void f0(T) { }
+template<typename T> void g0(T) { }
+template<typename T> struct x0 { }; // expected-note {{explicitly specialized declaration is here}}
+template<typename T> struct y0 { };
+
+// Should recover as if definition
+namespace noargs_body {
+#ifndef FIXING
+ template void g0(int) { } // expected-error {{function cannot be defined in an explicit instantiation; if this declaration is meant to be a function definition, remove the 'template' keyword}}
+#endif
+ template struct y0 { }; // expected-error {{class cannot be defined in an explicit instantiation; if this declaration is meant to be a class definition, remove the 'template' keyword}}
+}
+
+// Explicit specializations expected in global scope
+namespace exp_spec {
+#ifndef FIXING
+ template<> void f0<int>(int) { } // expected-error {{no function template matches function template specialization 'f0'}}
+ template<> struct x0<int> { }; // expected-error {{class template specialization of 'x0' must originally be declared in the global scope}}
+#endif
+}
+
+template<typename T> void f1(T) { }
+template<typename T> struct x1 { }; // expected-note {{explicitly specialized declaration is here}}
+
+// Should recover as if specializations,
+// thus also complain about not being in global scope.
+namespace args_bad {
+#ifndef FIXING
+ template void f1<int>(int) { } // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \
+ expected-error {{no function template matches function template specialization 'f1'}}
+ template struct x1<int> { }; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \
+ expected-error {{class template specialization of 'x1' must originally be declared in the global scope}}
+#endif
+}
+
+template<typename T> void f2(T) { }
+template<typename T> struct x2 { };
+
+// Should recover as if specializations
+template void f2<int>(int) { } // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}}
+template struct x2<int> { }; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
index aecbfb5649f3..d12feeff0bbc 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
@@ -163,7 +163,7 @@ namespace PR9877 {
template<> struct X<1>::Y { static const int Z = 1; };
const int X<0>::Y::Z;
- template<> const int X<1>::Y::Z; // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}}
+ template<> const int X<1>::Y::Z; // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}}
}
namespace PR9913 {
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
index ff24ad997dfd..38dc367b227e 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -emit-llvm -std=c++11 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns -emit-llvm -std=c++11 -o - %s | FileCheck %s
template<typename T>
struct X0 {
diff --git a/test/CXX/temp/temp.spec/temp.inst/p1.cpp b/test/CXX/temp/temp.spec/temp.inst/p1.cpp
index 8684fc4dabd9..adf812b714d1 100644
--- a/test/CXX/temp/temp.spec/temp.inst/p1.cpp
+++ b/test/CXX/temp/temp.spec/temp.inst/p1.cpp
@@ -33,24 +33,23 @@ namespace ScopedEnum {
ScopedEnum1<double>::E e1; // ok
ScopedEnum1<double>::E e2 = decltype(e2)::e; // expected-note {{in instantiation of enumeration 'ScopedEnum::ScopedEnum1<double>::E' requested here}}
- // The behavior for enums defined within function templates is not clearly
- // specified by the standard. We follow the rules for enums defined within
- // class templates.
+ // DR1484 specifies that enumerations cannot be separately instantiated,
+ // they will be instantiated with the rest of the template declaration.
template<typename T>
int f() {
enum class E {
- e = T::error
+ e = T::error // expected-error {{has no members}}
};
return (int)E();
}
- int test1 = f<int>();
+ int test1 = f<int>(); // expected-note {{here}}
template<typename T>
int g() {
enum class E {
e = T::error // expected-error {{has no members}}
};
- return E::e; // expected-note {{here}}
+ return E::e;
}
int test2 = g<int>(); // expected-note {{here}}
}