summaryrefslogtreecommitdiff
path: root/test/SemaTemplate
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r--test/SemaTemplate/address_space-dependent.cpp119
-rw-r--r--test/SemaTemplate/class-template-decl.cpp3
-rw-r--r--test/SemaTemplate/crash-unparsed-exception.cpp5
-rw-r--r--test/SemaTemplate/cxx17-inline-variables.cpp18
-rw-r--r--test/SemaTemplate/cxx1z-fold-expressions.cpp16
-rw-r--r--test/SemaTemplate/deduction-crash.cpp17
-rw-r--r--test/SemaTemplate/default-arguments-cxx0x.cpp27
-rw-r--r--test/SemaTemplate/default-expr-arguments-3.cpp2
-rw-r--r--test/SemaTemplate/explicit-instantiation.cpp12
-rw-r--r--test/SemaTemplate/explicit-specialization-member.cpp12
-rw-r--r--test/SemaTemplate/extern-templates.cpp7
-rw-r--r--test/SemaTemplate/instantiate-friend-function.cpp49
-rw-r--r--test/SemaTemplate/temp_arg_nontype_cxx1z.cpp7
-rw-r--r--test/SemaTemplate/temp_arg_template.cpp7
14 files changed, 282 insertions, 19 deletions
diff --git a/test/SemaTemplate/address_space-dependent.cpp b/test/SemaTemplate/address_space-dependent.cpp
new file mode 100644
index 0000000000000..f3d2f3c15d0d4
--- /dev/null
+++ b/test/SemaTemplate/address_space-dependent.cpp
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -x c++ -std=c++14 -fsyntax-only -verify %s
+
+template <int I, int J, int K>
+void car() {
+ int __attribute__((address_space(I))) __attribute__((address_space(J))) * Y; // expected-error {{multiple address spaces specified for type}}
+ int *__attribute__((address_space(I))) __attribute__((address_space(J))) * Z; // expected-error {{multiple address spaces specified for type}}
+
+ __attribute__((address_space(I))) int local; // expected-error {{automatic variable qualified with an address space}}
+ __attribute__((address_space(J))) int array[5]; // expected-error {{automatic variable qualified with an address space}}
+ __attribute__((address_space(I))) int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}}
+
+ __attribute__((address_space(J))) * x; // expected-error {{C++ requires a type specifier for all declarations}}
+
+ __attribute__((address_space(I))) float *B;
+
+ typedef __attribute__((address_space(J))) int AS2Int;
+ struct HasASFields {
+ AS2Int typedef_as_field; // expected-error {{field may not be qualified with an address space}}
+ };
+
+ struct _st {
+ int x, y;
+ } s __attribute((address_space(I))) = {1, 1};
+}
+
+template <int I>
+struct HasASTemplateFields {
+ __attribute__((address_space(I))) int as_field; // expected-error {{field may not be qualified with an address space}}
+};
+
+template <int I, int J>
+void foo(__attribute__((address_space(I))) float *a, // expected-note {{candidate template ignored: substitution failure [with I = 1, J = 2]: parameter may not be qualified with an address space}}
+ __attribute__((address_space(J))) float b) {
+ *a = 5.0f + b;
+}
+
+template void foo<1, 2>(float *, float); // expected-error {{explicit instantiation of 'foo' does not refer to a function template, variable template, member function, member class, or static data member}}
+
+template <int I>
+void neg() {
+ __attribute__((address_space(I))) int *bounds; // expected-error {{address space is negative}}
+}
+
+template <long int I>
+void tooBig() {
+ __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388598)}}
+}
+
+template <long int I>
+void correct() {
+ __attribute__((address_space(I))) int *bounds;
+}
+
+template <int I, int J>
+char *cmp(__attribute__((address_space(I))) char *x, __attribute__((address_space(J))) char *y) {
+ return x < y ? x : y; // expected-error {{comparison of distinct pointer types ('__attribute__((address_space(1))) char *' and '__attribute__((address_space(2))) char *')}}
+}
+
+typedef void ft(void);
+
+template <int I>
+struct fooFunction {
+ __attribute__((address_space(I))) void **const base = 0;
+
+ void *get_0(void) {
+ return base[0]; // expected-error {{cannot initialize return object of type 'void *' with an lvalue of type '__attribute__((address_space(1))) void *}}
+ }
+
+ __attribute__((address_space(I))) ft qf; // expected-error {{function type may not be qualified with an address space}}
+ __attribute__((address_space(I))) char *test3_val;
+
+ void test3(void) {
+ extern void test3_helper(char *p); // expected-note {{passing argument to parameter 'p' here}}
+ test3_helper(test3_val); // expected-error {{cannot initialize a parameter of type 'char *' with an lvalue of type '__attribute__((address_space(1))) char *'}}
+ }
+};
+
+template <typename T, int N>
+int GetAddressSpaceValue(T __attribute__((address_space(N))) * p) {
+ return N;
+}
+
+template <unsigned A> int __attribute__((address_space(A))) *same_template();
+template <unsigned B> int __attribute__((address_space(B))) *same_template();
+void test_same_template() { (void) same_template<0>(); }
+
+template <unsigned A> int __attribute__((address_space(A))) *different_template(); // expected-note {{candidate function [with A = 0]}}
+template <unsigned B> int __attribute__((address_space(B+1))) *different_template(); // expected-note {{candidate function [with B = 0]}}
+void test_different_template() { (void) different_template<0>(); } // expected-error {{call to 'different_template' is ambiguous}}
+
+template <typename T> struct partial_spec_deduce_as;
+template <typename T, unsigned AS>
+struct partial_spec_deduce_as <__attribute__((address_space(AS))) T *> {
+ static const unsigned value = AS;
+};
+
+int main() {
+ int __attribute__((address_space(1))) * p1;
+ int p = GetAddressSpaceValue(p1);
+
+ car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
+ HasASTemplateFields<1> HASTF;
+ neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
+ correct<0x7FFFF6>();
+ tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650>' requested here}}
+
+ __attribute__((address_space(1))) char *x;
+ __attribute__((address_space(2))) char *y;
+ cmp<1, 2>(x, y); // expected-note {{in instantiation of function template specialization 'cmp<1, 2>' requested here}}
+
+ fooFunction<1> ff;
+ ff.get_0(); // expected-note {{in instantiation of member function 'fooFunction<1>::get_0' requested here}}
+ ff.qf();
+ ff.test3(); // expected-note {{in instantiation of member function 'fooFunction<1>::test3' requested here}}
+
+ static_assert(partial_spec_deduce_as<int __attribute__((address_space(3))) *>::value == 3, "address space value has been incorrectly deduced");
+
+ return 0;
+}
diff --git a/test/SemaTemplate/class-template-decl.cpp b/test/SemaTemplate/class-template-decl.cpp
index 2e36cae14f600..c49154c6527a7 100644
--- a/test/SemaTemplate/class-template-decl.cpp
+++ b/test/SemaTemplate/class-template-decl.cpp
@@ -57,8 +57,7 @@ void f() {
template<typename T> class X; // expected-error{{expression}}
}
-template<typename T> class X1 var; // expected-warning{{variable templates are a C++14 extension}} \
- // expected-error {{variable has incomplete type 'class X1'}} \
+template<typename T> class X1 var; // expected-error {{variable has incomplete type 'class X1'}} \
// expected-note {{forward declaration of 'X1'}}
namespace M {
diff --git a/test/SemaTemplate/crash-unparsed-exception.cpp b/test/SemaTemplate/crash-unparsed-exception.cpp
index 1226b35deb701..3137d3fa197c5 100644
--- a/test/SemaTemplate/crash-unparsed-exception.cpp
+++ b/test/SemaTemplate/crash-unparsed-exception.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -fcxx-exceptions -fexceptions %s
+// expected-no-diagnostics
struct A {
virtual ~A();
@@ -11,7 +12,7 @@ struct C {
~D() throw();
};
struct E : A {
- D<int> d; //expected-error{{exception specification is not available until end of class definition}}
+ D<int> d;
};
- B<int> b; //expected-note{{in instantiation of template class 'B<int>' requested here}}
+ B<int> b;
};
diff --git a/test/SemaTemplate/cxx17-inline-variables.cpp b/test/SemaTemplate/cxx17-inline-variables.cpp
new file mode 100644
index 0000000000000..9e6761ee57aaf
--- /dev/null
+++ b/test/SemaTemplate/cxx17-inline-variables.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++17 -verify %s
+// expected-no-diagnostics
+template<bool> struct DominatorTreeBase {
+ static constexpr bool IsPostDominator = true;
+};
+extern template class DominatorTreeBase<false>;
+constexpr bool k = DominatorTreeBase<false>::IsPostDominator;
+
+namespace CompleteType {
+ template<unsigned N> constexpr int f(const bool (&)[N]) { return 0; }
+
+ template<bool ...V> struct X {
+ static constexpr bool arr[] = {V...};
+ static constexpr int value = f(arr);
+ };
+
+ constexpr int n = X<true>::value;
+}
diff --git a/test/SemaTemplate/cxx1z-fold-expressions.cpp b/test/SemaTemplate/cxx1z-fold-expressions.cpp
index aefee92f648a6..383f51df21dc7 100644
--- a/test/SemaTemplate/cxx1z-fold-expressions.cpp
+++ b/test/SemaTemplate/cxx1z-fold-expressions.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++1z -verify %s
+// RUN: %clang_cc1 -std=c++2a -verify %s
template<typename ...T> constexpr auto sum(T ...t) { return (... + t); }
template<typename ...T> constexpr auto product(T ...t) { return (t * ...); }
@@ -76,3 +77,18 @@ template<typename T, typename ...Ts> constexpr decltype(auto) apply(T &t, Ts ...
return (t.*....*ts);
}
static_assert(&apply(a, &A::b, &A::B::c, &A::B::C::d, &A::B::C::D::e) == &a.b.c.d.e);
+
+#if __cplusplus > 201703L
+// The <=> operator is unique among binary operators in not being a
+// fold-operator.
+// FIXME: This diagnostic is not great.
+template<typename ...T> constexpr auto spaceship1(T ...t) { return (t <=> ...); } // expected-error {{expected expression}}
+template<typename ...T> constexpr auto spaceship2(T ...t) { return (... <=> t); } // expected-error {{expected expression}}
+template<typename ...T> constexpr auto spaceship3(T ...t) { return (t <=> ... <=> 0); } // expected-error {{expected expression}}
+#endif
+
+// The GNU binary conditional operator ?: is not recognized as a fold-operator.
+// FIXME: Why not? This seems like it would be useful.
+template<typename ...T> constexpr auto binary_conditional1(T ...t) { return (t ?: ...); } // expected-error {{expected expression}}
+template<typename ...T> constexpr auto binary_conditional2(T ...t) { return (... ?: t); } // expected-error {{expected expression}}
+template<typename ...T> constexpr auto binary_conditional3(T ...t) { return (t ?: ... ?: 0); } // expected-error {{expected expression}}
diff --git a/test/SemaTemplate/deduction-crash.cpp b/test/SemaTemplate/deduction-crash.cpp
index 74a25865aa207..2c58fefa065fd 100644
--- a/test/SemaTemplate/deduction-crash.cpp
+++ b/test/SemaTemplate/deduction-crash.cpp
@@ -144,3 +144,20 @@ namespace var_template_partial_spec_incomplete {
template<typename T, typename U = void> int n<T *>; // expected-error +{{}} expected-note {{}}
int k = n<void *>;
}
+
+namespace deduceFunctionSpecializationForInvalidOutOfLineFunction {
+
+template <typename InputT, typename OutputT>
+struct SourceSelectionRequirement {
+ template<typename T>
+ OutputT evaluateSelectionRequirement(InputT &&Value) {
+ }
+};
+
+template <typename InputT, typename OutputT>
+OutputT SourceSelectionRequirement<InputT, OutputT>::
+evaluateSelectionRequirement<void>(InputT &&Value) { // expected-error {{cannot specialize a member of an unspecialized template}}
+ return Value;
+}
+
+}
diff --git a/test/SemaTemplate/default-arguments-cxx0x.cpp b/test/SemaTemplate/default-arguments-cxx0x.cpp
index d9fa2b4a825ec..c24ed12a0248c 100644
--- a/test/SemaTemplate/default-arguments-cxx0x.cpp
+++ b/test/SemaTemplate/default-arguments-cxx0x.cpp
@@ -87,3 +87,30 @@ namespace PR13986 {
A<1> m_target;
};
}
+
+// rdar://problem/34167492
+// Template B is instantiated during checking if defaulted A copy constructor
+// is constexpr. For this we check if S<int> copy constructor is constexpr. And
+// for this we check S constructor template with default argument that mentions
+// template B. In turn, template instantiation triggers checking defaulted
+// members exception spec. The problem is that it checks defaulted members not
+// for instantiated class only, but all defaulted members so far. In this case
+// we try to check exception spec for A default constructor which requires
+// initializer for the field _a. But initializers are added after constexpr
+// check so we reject the code because cannot find _a initializer.
+namespace rdar34167492 {
+ template <typename T> struct B { using type = bool; };
+
+ template <typename T> struct S {
+ S() noexcept;
+
+ template <typename U, typename B<U>::type = true>
+ S(const S<U>&) noexcept;
+ };
+
+ class A {
+ A() noexcept = default;
+ A(const A&) noexcept = default;
+ S<int> _a{};
+ };
+}
diff --git a/test/SemaTemplate/default-expr-arguments-3.cpp b/test/SemaTemplate/default-expr-arguments-3.cpp
index 173609c04585d..4449eb7100aa3 100644
--- a/test/SemaTemplate/default-expr-arguments-3.cpp
+++ b/test/SemaTemplate/default-expr-arguments-3.cpp
@@ -21,7 +21,7 @@ namespace PR28795 {
}
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct class2 definition
-// CHECK-NEXT: TemplateArgument type 'int'
+// CHECK: TemplateArgument type 'int'
// CHECK: LambdaExpr {{.*}} 'class (lambda at
// CHECK: ParmVarDecl {{.*}} used f 'enum foo' cinit
// CHECK-NEXT: DeclRefExpr {{.*}} 'enum foo' EnumConstant {{.*}} 'a' 'enum foo'
diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp
index 42d9f4d332a99..d88c50bc29de3 100644
--- a/test/SemaTemplate/explicit-instantiation.cpp
+++ b/test/SemaTemplate/explicit-instantiation.cpp
@@ -124,10 +124,10 @@ namespace PR10086 {
namespace undefined_static_data_member {
template<typename T> struct A {
static int a; // expected-note {{here}}
- template<typename U> static int b; // expected-note {{here}} expected-warning {{extension}}
+ template<typename U> static int b; // expected-note {{here}} expected-warning 0+ {{extension}}
};
struct B {
- template<typename U> static int c; // expected-note {{here}} expected-warning {{extension}}
+ template<typename U> static int c; // expected-note {{here}} expected-warning 0+ {{extension}}
};
template int A<int>::a; // expected-error {{explicit instantiation of undefined static data member 'a' of class template 'undefined_static_data_member::A<int>'}}
@@ -137,14 +137,14 @@ namespace undefined_static_data_member {
template<typename T> struct C {
static int a;
- template<typename U> static int b; // expected-warning {{extension}}
+ template<typename U> static int b; // expected-warning 0+ {{extension}}
};
struct D {
- template<typename U> static int c; // expected-warning {{extension}}
+ template<typename U> static int c; // expected-warning 0+ {{extension}}
};
template<typename T> int C<T>::a;
- template<typename T> template<typename U> int C<T>::b; // expected-warning {{extension}}
- template<typename U> int D::c; // expected-warning {{extension}}
+ template<typename T> template<typename U> int C<T>::b; // expected-warning 0+ {{extension}}
+ template<typename U> int D::c; // expected-warning 0+ {{extension}}
template int C<int>::a;
template int C<int>::b<int>;
diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp
index c0c36808b4920..e8165ac9ca7ad 100644
--- a/test/SemaTemplate/explicit-specialization-member.cpp
+++ b/test/SemaTemplate/explicit-specialization-member.cpp
@@ -38,24 +38,20 @@ namespace PR18246 {
template<typename T>
template<int N>
- void Baz<T>::bar() { // expected-note {{couldn't infer template argument 'N'}}
+ void Baz<T>::bar() {
}
- // FIXME: We shouldn't try to match this against a prior declaration if
- // template parameter matching failed.
template<typename T>
- void Baz<T>::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}} \
- // expected-error {{no function template matches}}
+ void Baz<T>::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}}
}
}
namespace PR19340 {
template<typename T> struct Helper {
- template<int N> static void func(const T *m) {} // expected-note {{failed template argument deduction}}
+ template<int N> static void func(const T *m) {}
};
-template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}} \
- // expected-error {{no function template matches}}
+template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}}
}
namespace SpecLoc {
diff --git a/test/SemaTemplate/extern-templates.cpp b/test/SemaTemplate/extern-templates.cpp
index 5eb9c9db127c8..acbc9d57122ef 100644
--- a/test/SemaTemplate/extern-templates.cpp
+++ b/test/SemaTemplate/extern-templates.cpp
@@ -71,3 +71,10 @@ extern template void X1<const void*>::g(const void*);
void g_X1_2(X1<const void *> x1, const void *ptr) {
x1.g(ptr);
}
+
+namespace static_const_member {
+ template <typename T> struct A { static const int n; };
+ template <typename T> const int A<T>::n = 3;
+ extern template struct A<int>;
+ int arr[A<int>::n];
+}
diff --git a/test/SemaTemplate/instantiate-friend-function.cpp b/test/SemaTemplate/instantiate-friend-function.cpp
new file mode 100644
index 0000000000000..08602d522df0f
--- /dev/null
+++ b/test/SemaTemplate/instantiate-friend-function.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -S -triple %itanium_abi_triple -std=c++11 -emit-llvm %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+namespace PR10856 {
+ template<typename T> class C;
+
+ template<typename S, typename R = S> C<R> operator - (C<S> m0, C<S> m1);
+ template<typename T> class C {
+ public:
+ template<typename S, typename R> friend C<R> operator - (C<S> m0, C<S> m1);
+ };
+
+ template<typename S, typename R> inline C<R> operator - (C<S> m0, C<S> m1) {
+ C<R> ret;
+ return ret;
+ }
+};
+
+int PR10856_main(int argc, char** argv) {
+ using namespace PR10856;
+ C<int> a;
+ a-a;
+ return 0;
+}
+
+// PR10856::C<int> PR10856::operator-<int, int>(PR10856::C<int>, PR10856::C<int>)
+// CHECK: define {{.*}} @_ZN7PR10856miIiiEENS_1CIT0_EENS1_IT_EES5_
+
+namespace PR10856_Root {
+ template<typename Value, typename Defaulted = void>
+ bool g(Value value);
+
+ template<typename ClassValue> class MyClass {
+ private:
+ template<typename Value, typename Defaulted>
+ friend bool g(Value value);
+ };
+}
+
+namespace PR10856_Root {
+ void f() {
+ MyClass<int> value;
+ g(value);
+ }
+}
+
+// bool PR10856_Root::g<PR10856_Root::MyClass<int>, void>(PR10856_Root::MyClass<int>)
+// CHECK: call {{.*}} @_ZN12PR10856_Root1gINS_7MyClassIiEEvEEbT_
diff --git a/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
index c1fcedd58d134..1a84d545c6474 100644
--- a/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
+++ b/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -23,6 +23,9 @@ namespace Array {
A<const char*, &(&x)[1]> h; // expected-error {{refers to subobject '&x + 1'}}
A<const char*, 0> i; // expected-error {{not allowed in a converted constant}}
A<const char*, nullptr> j;
+
+ extern char aub[];
+ A<char[], aub> k;
}
namespace Function {
@@ -235,6 +238,10 @@ namespace Auto {
constexpr char s[] = "test";
template<const auto* p> struct S { };
S<s> p;
+
+ template<typename R, typename P, R F(P)> struct A {};
+ template<typename R, typename P, R F(P)> void x(A<R, P, F> a);
+ void g(int) { x(A<void, int, &g>()); }
}
namespace DecltypeAuto {
diff --git a/test/SemaTemplate/temp_arg_template.cpp b/test/SemaTemplate/temp_arg_template.cpp
index 8f59dd724cc21..59deae701801e 100644
--- a/test/SemaTemplate/temp_arg_template.cpp
+++ b/test/SemaTemplate/temp_arg_template.cpp
@@ -141,3 +141,10 @@ namespace PR32185 {
template<template<typename T, T> class U> struct A {};
template<template<typename T, T> class U> struct B : A<U> {};
}
+
+namespace PR10147 {
+ template<typename T> struct A {};
+ template<typename T = int> struct A;
+ template<template<typename...> class A> void f(A<int>*) { A<> a; } // expected-warning 0-1{{extension}}
+ void g() { f((A<>*)0); }
+}