diff options
author | dim <dim@FreeBSD.org> | 2013-12-22 00:07:40 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-12-22 00:07:40 +0000 |
commit | 952eddef9aff85b1e92626e89baaf7a360e2ac85 (patch) | |
tree | df8df0b0067b381eab470a3b8f28d14a552a6340 /test/CXX/temp | |
parent | ea266cad53e3d49771fa38103913d3ec7a166694 (diff) | |
download | FreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.zip FreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.tar.gz |
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
https://llvm.org/svn/llvm-project/cfe/branches/release_34@197841
Diffstat (limited to 'test/CXX/temp')
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 c4db002..3f70ca7 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 afd9b4b..2d46502 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 0000000..a49db51 --- /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 f8cc009..2884be14 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 2eae112..8a3168e 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 6d22f88..60c60cb 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 e036cef..8571a14 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 4b899e4..b26abb6 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 0000000..c24d5a9 --- /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 ce19582..e7a6236 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 9453798..3681d77 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 0000000..4960a2b --- /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 67efc4e..c258682 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 0000000..eccbb89 --- /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 0000000..93f8ff1 --- /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 0000000..a4d7914 --- /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 aecbfb5..d12feef 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 ff24ad9..38dc367 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 8684fc4..adf812b 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}} } |