127 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++98 %s -Wno-c++11-extensions2// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++17 %s3// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx20 -std=c++20 %s4 5// C++98:6// A non-type template-parameter shall not be declared to have7// floating point, class, or void type.8struct A; // expected-note {{forward declaration}}9 10template<double d> class X; // cxx17-error{{cannot have type}}11template<double* pd> class Y; //OK 12template<double& rd> class Z; //OK 13 14template<A a> class X0; // expected-error{{has incomplete type 'A'}}15 16struct A {};17 18template<A a> class X0b; // cxx17-error{{cannot have type 'A' before C++20}}19 20typedef void VOID;21template<VOID a> class X01; // expected-error{{has incomplete type 'VOID'}}22 23// C++11 disallows rvalue references.24 25template<int &R> struct lval_ref;26template<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 list31template<_Complex float ci> struct ComplexFloat; // cxx17-error {{cannot have type '_Complex float' before C++20}}32template<_Complex int ci> struct ComplexInt; // cxx17-error {{cannot have type '_Complex int' before C++20}}33template<_BitInt(42) ei> struct ExtInt;34 35// atomic types aren't scalar types36template<_Atomic float ci> struct AtomicFloat; // expected-error {{cannot have type '_Atomic(float)'}}37template<_Atomic int ci> struct AtomicInt; // expected-error {{cannot have type '_Atomic(int)'}}38 39// we allow vector types as an extension40typedef __attribute__((ext_vector_type(4))) int VI4;41typedef __attribute__((ext_vector_type(4))) float VF4;42template<VI4> struct VectorInt; // cxx17-error {{cannot have type 'VI4'}}43template<VF4> struct VectorFloat; // cxx17-error {{cannot have type 'VF4'}}44 45struct A2 {};46 47struct 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.52struct B : A, public A2 {53 int a;54private:55 void f();56 static int s;57public: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 _BitInt(42) ei;67 VI4 vi4;68 VF4 vf4;69};70 71template<B> struct ClassNTTP {}; // cxx17-error {{cannot have type 'B'}}72 73template<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 76struct BadBase77 : RRef {}; // cxx20-note {{'BadBase' is not a structural type because it has a base class of non-structural type 'RRef'}}78template<BadBase> struct WithBadBase {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}79 80struct 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};83template<BadField> struct WithBadField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}84 85struct 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};88template<BadFieldArray> struct WithBadFieldArray {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}89 90struct ProtectedBase91 : protected A {}; // cxx20-note {{'ProtectedBase' is not a structural type because it has a base class that is not public}}92template<ProtectedBase> struct WithProtectedBase {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}93 94struct PrivateBase95 : private A {}; // cxx20-note {{'PrivateBase' is not a structural type because it has a base class that is not public}}96template<PrivateBase> struct WithPrivateBase {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}97 98class Private2Base99 : A {}; // cxx20-note {{'Private2Base' is not a structural type because it has a base class that is not public}}100template<Private2Base> struct WithPrivate2Base {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}101 102struct ProtectedField {103protected:104 A r; // cxx20-note {{'ProtectedField' is not a structural type because it has a non-static data member that is not public}}105};106template<ProtectedField> struct WithProtectedField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}107 108struct PrivateField {109private:110 A r; // cxx20-note {{'PrivateField' is not a structural type because it has a non-static data member that is not public}}111};112template<PrivateField> struct WithPrivateField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}113 114class 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};117template<Private2Field> struct WithPrivate2Field {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}118 119struct MutableField {120 mutable int n; // cxx20-note {{'MutableField' is not a structural type because it has a mutable non-static data member}}121};122template<MutableField> struct WithMutableField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}123 124template<typename T> struct BadExtType { T t; }; // cxx20-note 2{{has a non-static data member of non-structural type}}125template<BadExtType<_Atomic float> > struct AtomicFloatField; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}126template<BadExtType<_Atomic int> > struct AtomicInt; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}127