diff options
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r-- | test/SemaTemplate/address_space-dependent.cpp | 119 | ||||
-rw-r--r-- | test/SemaTemplate/class-template-decl.cpp | 3 | ||||
-rw-r--r-- | test/SemaTemplate/crash-unparsed-exception.cpp | 5 | ||||
-rw-r--r-- | test/SemaTemplate/cxx17-inline-variables.cpp | 18 | ||||
-rw-r--r-- | test/SemaTemplate/cxx1z-fold-expressions.cpp | 16 | ||||
-rw-r--r-- | test/SemaTemplate/deduction-crash.cpp | 17 | ||||
-rw-r--r-- | test/SemaTemplate/default-arguments-cxx0x.cpp | 27 | ||||
-rw-r--r-- | test/SemaTemplate/default-expr-arguments-3.cpp | 2 | ||||
-rw-r--r-- | test/SemaTemplate/explicit-instantiation.cpp | 12 | ||||
-rw-r--r-- | test/SemaTemplate/explicit-specialization-member.cpp | 12 | ||||
-rw-r--r-- | test/SemaTemplate/extern-templates.cpp | 7 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-friend-function.cpp | 49 | ||||
-rw-r--r-- | test/SemaTemplate/temp_arg_nontype_cxx1z.cpp | 7 | ||||
-rw-r--r-- | test/SemaTemplate/temp_arg_template.cpp | 7 |
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); } +} |