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 4 5 // C++98: 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}} 9 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 13 14 template<A a> class X0; // expected-error{{has incomplete type 'A'}} 15 16 struct A {}; 17 18 template<A a> class X0b; // cxx17-error{{cannot have type 'A' before C++20}} 19 20 typedef void VOID; 21 template<VOID a> class X01; // expected-error{{has incomplete type 'VOID'}} 22 23 // C++11 disallows rvalue references. 24 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 &&'}} 27 28 // C++20 requires a structural type. In addition to the above cases, this allows: 29 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<_ExtInt(42) ei> struct ExtInt; 34 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)'}} 38 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'}} 44 45 struct A2 {}; 46 47 struct RRef { 48 int &&r; // cxx20-note 1+{{'RRef' is not a structural type because it has a non-static data member of rvalue reference type}} 49 }; 50 51 // class types with all public members and bases, no mutable state, and no rvalue references. 52 struct B : A, public A2 { 53 int a; 54 private: 55 void f(); 56 static int s; 57 public: 58 float g; 59 int &r = a; 60 void *p; 61 A2 a2; 62 RRef *ptr_to_bad; 63 RRef &ref_to_bad = *ptr_to_bad; 64 _Complex int ci; 65 _Complex float cf; 66 _ExtInt(42) ei; 67 VI4 vi4; 68 VF4 vf4; 69 }; 70 71 template<B> struct ClassNTTP {}; // cxx17-error {{cannot have type 'B'}} 72 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}} 75 76 struct BadBase 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}} 79 80 struct BadField { 81 RRef r; // cxx20-note {{'BadField' is not a structural type because it has a non-static data member of non-structural type 'RRef'}} 82 }; 83 template<BadField> struct WithBadField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}} 84 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'}} 87 }; 88 template<BadFieldArray> struct WithBadFieldArray {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}} 89 90 struct ProtectedBase 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}} 93 94 struct PrivateBase 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}} 97 98 class Private2Base 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}} 101 102 struct ProtectedField { 103 protected: 104 A r; // cxx20-note {{'ProtectedField' is not a structural type because it has a non-static data member that is not public}} 105 }; 106 template<ProtectedField> struct WithProtectedField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}} 107 108 struct PrivateField { 109 private: 110 A r; // cxx20-note {{'PrivateField' is not a structural type because it has a non-static data member that is not public}} 111 }; 112 template<PrivateField> struct WithPrivateField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}} 113 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}} 116 }; 117 template<Private2Field> struct WithPrivate2Field {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}} 118 119 struct MutableField { 120 mutable int n; // cxx20-note {{'MutableField' is not a structural type because it has a mutable non-static data member}} 121 }; 122 template<MutableField> struct WithMutableField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}} 123 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}} 127