1 // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++98 %s -Wno-c++11-extensions
2 // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++17 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx20 -std=c++20 %s
6 // A non-type template-parameter shall not be declared to have
7 // floating point, class, or void type.
8 struct A
; // expected-note {{forward declaration}}
10 template<double d
> class X
; // cxx17-error{{cannot have type}}
11 template<double* pd
> class Y
; //OK
12 template<double& rd
> class Z
; //OK
14 template<A a
> class X0
; // expected-error{{has incomplete type 'A'}}
18 template<A a
> class X0b
; // cxx17-error{{cannot have type 'A' before C++20}}
21 template<VOID a
> class X01
; // expected-error{{has incomplete type 'VOID'}}
23 // C++11 disallows rvalue references.
25 template<int &R
> struct lval_ref
;
26 template<int &&R
> struct rval_ref
; // expected-warning 0-1{{extension}} expected-error {{non-type template parameter has rvalue reference type 'int &&'}}
28 // C++20 requires a structural type. In addition to the above cases, this allows:
30 // arbitrary scalar types; we generally include complex types in that list
31 template<_Complex
float ci
> struct ComplexFloat
; // cxx17-error {{cannot have type '_Complex float' before C++20}}
32 template<_Complex
int ci
> struct ComplexInt
; // cxx17-error {{cannot have type '_Complex int' before C++20}}
33 template<_BitInt(42) ei
> struct ExtInt
;
35 // atomic types aren't scalar types
36 template<_Atomic
float ci
> struct AtomicFloat
; // expected-error {{cannot have type '_Atomic(float)'}}
37 template<_Atomic
int ci
> struct AtomicInt
; // expected-error {{cannot have type '_Atomic(int)'}}
39 // we allow vector types as an extension
40 typedef __attribute__((ext_vector_type(4))) int VI4
;
41 typedef __attribute__((ext_vector_type(4))) float VF4
;
42 template<VI4
> struct VectorInt
; // cxx17-error {{cannot have type 'VI4'}}
43 template<VF4
> struct VectorFloat
; // cxx17-error {{cannot have type 'VF4'}}
48 int &&r
; // cxx20-note 1+{{'RRef' is not a structural type because it has a non-static data member of rvalue reference type}}
51 // class types with all public members and bases, no mutable state, and no rvalue references.
52 struct B
: A
, public A2
{
63 RRef
&ref_to_bad
= *ptr_to_bad
;
71 template<B
> struct ClassNTTP
{}; // cxx17-error {{cannot have type 'B'}}
73 template<RRef
> struct WithRRef
{}; // cxx17-error {{cannot have type 'RRef'}}
74 // cxx20-error@-1 {{type 'RRef' of non-type template parameter is not a structural type}}
77 : RRef
{}; // cxx20-note {{'BadBase' is not a structural type because it has a base class of non-structural type 'RRef'}}
78 template<BadBase
> struct WithBadBase
{}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
81 RRef r
; // cxx20-note {{'BadField' is not a structural type because it has a non-static data member of non-structural type 'RRef'}}
83 template<BadField
> struct WithBadField
{}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
85 struct BadFieldArray
{
86 RRef r
[3][2]; // cxx20-note {{'BadFieldArray' is not a structural type because it has a non-static data member of non-structural type 'RRef'}}
88 template<BadFieldArray
> struct WithBadFieldArray
{}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
91 : protected A
{}; // cxx20-note {{'ProtectedBase' is not a structural type because it has a base class that is not public}}
92 template<ProtectedBase
> struct WithProtectedBase
{}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
95 : private A
{}; // cxx20-note {{'PrivateBase' is not a structural type because it has a base class that is not public}}
96 template<PrivateBase
> struct WithPrivateBase
{}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
99 : A
{}; // cxx20-note {{'Private2Base' is not a structural type because it has a base class that is not public}}
100 template<Private2Base
> struct WithPrivate2Base
{}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
102 struct ProtectedField
{
104 A r
; // cxx20-note {{'ProtectedField' is not a structural type because it has a non-static data member that is not public}}
106 template<ProtectedField
> struct WithProtectedField
{}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
108 struct PrivateField
{
110 A r
; // cxx20-note {{'PrivateField' is not a structural type because it has a non-static data member that is not public}}
112 template<PrivateField
> struct WithPrivateField
{}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
114 class Private2Field
{
115 A r
; // cxx20-note {{'Private2Field' is not a structural type because it has a non-static data member that is not public}}
117 template<Private2Field
> struct WithPrivate2Field
{}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
119 struct MutableField
{
120 mutable int n
; // cxx20-note {{'MutableField' is not a structural type because it has a mutable non-static data member}}
122 template<MutableField
> struct WithMutableField
{}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
124 template<typename T
> struct BadExtType
{ T t
; }; // cxx20-note 2{{has a non-static data member of non-structural type}}
125 template<BadExtType
<_Atomic
float> > struct AtomicFloatField
; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
126 template<BadExtType
<_Atomic
int> > struct AtomicInt
; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}