aboutsummaryrefslogtreecommitdiff
path: root/test/SemaTemplate
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r--test/SemaTemplate/attributes.cpp4
-rw-r--r--test/SemaTemplate/exception-spec-crash.cpp4
-rw-r--r--test/SemaTemplate/friend.cpp75
-rw-r--r--test/SemaTemplate/instantiate-init.cpp6
-rw-r--r--test/SemaTemplate/instantiation-depth-default.cpp2
-rw-r--r--test/SemaTemplate/member-specialization.cpp11
-rw-r--r--test/SemaTemplate/temp_arg_nontype_cxx1z.cpp43
-rw-r--r--test/SemaTemplate/temp_arg_pack.cpp16
-rw-r--r--test/SemaTemplate/typename-specifier-3.cpp56
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
+}