diff options
Diffstat (limited to 'test/SemaTemplate')
| -rw-r--r-- | test/SemaTemplate/attributes.cpp | 4 | ||||
| -rw-r--r-- | test/SemaTemplate/exception-spec-crash.cpp | 4 | ||||
| -rw-r--r-- | test/SemaTemplate/friend.cpp | 75 | ||||
| -rw-r--r-- | test/SemaTemplate/instantiate-init.cpp | 6 | ||||
| -rw-r--r-- | test/SemaTemplate/instantiation-depth-default.cpp | 2 | ||||
| -rw-r--r-- | test/SemaTemplate/member-specialization.cpp | 11 | ||||
| -rw-r--r-- | test/SemaTemplate/temp_arg_nontype_cxx1z.cpp | 43 | ||||
| -rw-r--r-- | test/SemaTemplate/temp_arg_pack.cpp | 16 | ||||
| -rw-r--r-- | test/SemaTemplate/typename-specifier-3.cpp | 56 |
9 files changed, 210 insertions, 7 deletions
diff --git a/test/SemaTemplate/attributes.cpp b/test/SemaTemplate/attributes.cpp index 7634b937c906..7a04c4705bf2 100644 --- a/test/SemaTemplate/attributes.cpp +++ b/test/SemaTemplate/attributes.cpp @@ -55,11 +55,11 @@ namespace PR9049 { } // CHECK: FunctionTemplateDecl {{.*}} HasAnnotations -// CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR" // CHECK: AnnotateAttr {{.*}} "ANNOTATE_FOO" +// CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR" // CHECK: FunctionDecl {{.*}} HasAnnotations // CHECK: TemplateArgument type 'int' -// CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR" // CHECK: AnnotateAttr {{.*}} "ANNOTATE_FOO" +// CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR" template<typename T> [[clang::annotate("ANNOTATE_FOO"), clang::annotate("ANNOTATE_BAR")]] void HasAnnotations(); void UseAnnotations() { HasAnnotations<int>(); } diff --git a/test/SemaTemplate/exception-spec-crash.cpp b/test/SemaTemplate/exception-spec-crash.cpp index 4d9355974c9e..ebbb30a2c23b 100644 --- a/test/SemaTemplate/exception-spec-crash.cpp +++ b/test/SemaTemplate/exception-spec-crash.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -DCXX_EXCEPTIONS -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -Wno-defaulted-function-deleted +// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -DCXX_EXCEPTIONS -fsyntax-only -verify %s -Wno-defaulted-function-deleted template <class _Tp> struct is_nothrow_move_constructible { static const bool value = false; diff --git a/test/SemaTemplate/friend.cpp b/test/SemaTemplate/friend.cpp index ef1aed50e626..777682be3f1b 100644 --- a/test/SemaTemplate/friend.cpp +++ b/test/SemaTemplate/friend.cpp @@ -47,3 +47,78 @@ inline void foo() {} inline void bar() {} C<int> c; } + +namespace qualified_friend { + void f(int); // expected-note 2{{type mismatch at 1st parameter}} + template<typename T> void f(T*); // expected-note 2{{could not match 'type-parameter-0-0 *' against 'double'}} + template<typename T> void nondep(); + + template<typename> struct X1 { + friend void qualified_friend::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend'}} + friend void qualified_friend::g(); // expected-error {{friend declaration of 'g' does not match any declaration in namespace 'qualified_friend'}} + }; + template<typename T> struct X2 { + friend void qualified_friend::f(T); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend'}} + }; + X1<int> xi; + X2<double> xd; // expected-note {{in instantiation of}} + X2<int> x2i; + + struct Y { + void f(int); // expected-note 2{{type mismatch at 1st parameter}} + template<typename T> void f(T*); // expected-note 2{{could not match 'type-parameter-0-0 *' against 'double'}} + template<typename T> void nondep(); + }; + + template<typename> struct Z1 { + friend void Y::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend::Y'}} + friend void Y::g(); // expected-error {{friend declaration of 'g' does not match any declaration in 'qualified_friend::Y'}} + }; + template<typename T> struct Z2 { + friend void Y::f(T); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend::Y'}} + }; + Z1<int> zi; + Z2<double> zd; // expected-note {{in instantiation of}} + Z2<int> z2i; + + template<typename T> + struct OK { + friend void qualified_friend::f(int); + friend void qualified_friend::f(int*); + friend void qualified_friend::f(T*); + friend void qualified_friend::f<T>(T*); + friend void qualified_friend::nondep<int>(); + friend void qualified_friend::nondep<T>(); + + friend void Y::f(int); + friend void Y::f(int*); + friend void Y::f(T*); + friend void Y::f<T>(T*); + friend void Y::nondep<int>(); + friend void Y::nondep<T>(); + }; + OK<float> ok; +} + +namespace qualified_friend_finds_nothing { + // FIXME: The status of this example is unclear. For now, we diagnose if the + // qualified declaration has nothing it can redeclare, but allow qualified + // lookup to find later-declared function templates during instantiation. + // + // This matches the behavior of GCC, EDG, ICC, and MSVC (except that GCC and + // ICC bizarrely accept the instantiation of B<float>). + namespace N {} + + template<typename T> struct A { + friend void N::f(T); // expected-error {{friend declaration of 'f' does not match}} + }; + namespace N { void f(); } // expected-note {{different number of parameters}} + + template<typename T> struct B { + friend void N::f(T); // expected-error {{friend declaration of 'f' does not match}} + }; + B<float> bf; // expected-note {{in instantiation of}} + + namespace N { void f(int); } + B<int> bi; // ok?! +} diff --git a/test/SemaTemplate/instantiate-init.cpp b/test/SemaTemplate/instantiate-init.cpp index 51fa6955d0c0..b58ad3a15763 100644 --- a/test/SemaTemplate/instantiate-init.cpp +++ b/test/SemaTemplate/instantiate-init.cpp @@ -115,8 +115,10 @@ namespace PR13064 { struct A { explicit A(int); }; // expected-note{{here}} template<typename T> struct B { T a { 0 }; }; B<A> b; - template<typename T> struct C { T a = { 0 }; }; // expected-error{{explicit}} - C<A> c; // expected-note {{in instantiation of default member initializer}} + template <typename T> struct C { // expected-note {{in instantiation of default member initializer}} + T a = {0}; // expected-error{{explicit}} + }; + C<A> c; // expected-note {{in evaluation of exception spec}} } namespace PR16903 { diff --git a/test/SemaTemplate/instantiation-depth-default.cpp b/test/SemaTemplate/instantiation-depth-default.cpp index 3d89aa18ca43..69efa253e3fe 100644 --- a/test/SemaTemplate/instantiation-depth-default.cpp +++ b/test/SemaTemplate/instantiation-depth-default.cpp @@ -14,4 +14,4 @@ template<int N, typename T> struct X : X<N+1, T*> {}; X<0, int> x; // expected-note {{in instantiation of}} // FIXME: It crashes. Investigating. -// UNSUPPORTED: mingw32 +// UNSUPPORTED: windows-gnu diff --git a/test/SemaTemplate/member-specialization.cpp b/test/SemaTemplate/member-specialization.cpp new file mode 100644 index 000000000000..ea30a7a0cd74 --- /dev/null +++ b/test/SemaTemplate/member-specialization.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++17 -verify %s +// expected-no-diagnostics + +template<typename T, typename U> struct X { + template<typename V> const V &as() { return V::error; } + template<> const U &as<U>() { return u; } + U u; +}; +int f(X<int, int> x) { + return x.as<int>(); +} diff --git a/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp index 1a84d545c647..b887c7f47d3c 100644 --- a/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp +++ b/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp @@ -335,3 +335,46 @@ namespace Nested { void g(int, int); using Int = A<int>::B<&g>::param2; } + +namespace rdar41852459 { +template <auto V> struct G {}; + +template <class T> struct S { + template <auto V> void f() { + G<V> x; + } + template <auto *PV> void f2() { + G<PV> x; + } + template <decltype(auto) V> void f3() { + G<V> x; + } +}; + +template <auto *PV> struct I {}; + +template <class T> struct K { + template <auto *PV> void f() { + I<PV> x; + } + template <auto V> void f2() { + I<V> x; + } + template <decltype(auto) V> void f3() { + I<V> x; + } +}; + +template <decltype(auto)> struct L {}; +template <class T> struct M { + template <auto *PV> void f() { + L<PV> x; + } + template <auto V> void f() { + L<V> x; + } + template <decltype(auto) V> void f() { + L<V> x; + } +}; +} diff --git a/test/SemaTemplate/temp_arg_pack.cpp b/test/SemaTemplate/temp_arg_pack.cpp index b79dca78bced..26e3f6ba5e5e 100644 --- a/test/SemaTemplate/temp_arg_pack.cpp +++ b/test/SemaTemplate/temp_arg_pack.cpp @@ -6,3 +6,19 @@ namespace deduce_pack_non_pack { template <typename T> void g(C<A<T>>); // expected-note {{candidate template ignored: deduced type 'C<A<[...], (no argument)>>' of 1st parameter does not match adjusted type 'C<A<[...], int>>' of argument [with T = bool]}} void h(C<A<bool, int>> &x) { g(x); } // expected-error {{no matching function}} } + +namespace pr39231 { + template<typename T, T ...V> struct integer_sequence {}; + + template <typename T, T... A, T... B> + int operator^(integer_sequence<T, A...> a, // expected-note {{deduced conflicting values for parameter 'A' (<1, 2, 3> vs. <4, 5, 6>)}} + integer_sequence<T, A...> b); + + int v = integer_sequence<int, 1, 2, 3>{} ^ integer_sequence<int, 4, 5, 6>{}; // expected-error {{invalid operands}} + + template <typename T, T... A, T... B> + integer_sequence<T, A + B...> operator+(integer_sequence<T, A...> a, + integer_sequence<T, B...> b); + integer_sequence<int, 5, 7, 9> w = + integer_sequence<int, 1, 2, 3>{} + integer_sequence<int, 4, 5, 6>{}; +} diff --git a/test/SemaTemplate/typename-specifier-3.cpp b/test/SemaTemplate/typename-specifier-3.cpp index dfab5a0130f8..dc9d00601d48 100644 --- a/test/SemaTemplate/typename-specifier-3.cpp +++ b/test/SemaTemplate/typename-specifier-3.cpp @@ -18,3 +18,59 @@ B c() { template<class T> struct test2 { T b() { return typename T::a; } }; // expected-error{{expected '(' for function-style cast or type construction}} template<class T> struct test3 { T b() { return typename a; } }; // expected-error{{expected a qualified name after 'typename'}} template<class T> struct test4 { T b() { return typename ::a; } }; // expected-error{{refers to non-type member}} expected-error{{expected '(' for function-style cast or type construction}} + +// PR12884 +namespace PR12884_original { + template <typename T> struct A { + struct B { + template <typename U> struct X {}; + typedef int arg; + }; + struct C { + typedef B::X<typename B::arg> x; // expected-error {{missing 'typename'}} + }; + }; + + template <> struct A<int>::B { + template <int N> struct X {}; + static const int arg = 0; + }; + + A<int>::C::x a; +} +namespace PR12884_half_fixed { + template <typename T> struct A { + struct B { + template <typename U> struct X {}; + typedef int arg; + }; + struct C { + typedef typename B::X<typename B::arg> x; // expected-error {{use 'template'}} expected-error {{refers to non-type}} + }; + }; + + template <> struct A<int>::B { + template <int N> struct X {}; + static const int arg = 0; // expected-note {{here}} + }; + + A<int>::C::x a; // expected-note {{here}} +} +namespace PR12884_fixed { + template <typename T> struct A { + struct B { + template <typename U> struct X {}; + typedef int arg; + }; + struct C { + typedef typename B::template X<B::arg> x; + }; + }; + + template <> struct A<int>::B { + template <int N> struct X {}; + static const int arg = 0; + }; + + A<int>::C::x a; // ok +} |
