127 lines
5.8 KiB
C++
127 lines
5.8 KiB
C++
|
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++98 %s -Wno-c++11-extensions
|
||
|
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++17 %s
|
||
|
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx20 -std=c++20 %s
|
||
|
|
||
|
// C++98:
|
||
|
// A non-type template-parameter shall not be declared to have
|
||
|
// floating point, class, or void type.
|
||
|
struct A; // expected-note {{forward declaration}}
|
||
|
|
||
|
template<double d> class X; // cxx17-error{{cannot have type}}
|
||
|
template<double* pd> class Y; //OK
|
||
|
template<double& rd> class Z; //OK
|
||
|
|
||
|
template<A a> class X0; // expected-error{{has incomplete type 'A'}}
|
||
|
|
||
|
struct A {};
|
||
|
|
||
|
template<A a> class X0b; // cxx17-error{{cannot have type 'A' before C++20}}
|
||
|
|
||
|
typedef void VOID;
|
||
|
template<VOID a> class X01; // expected-error{{has incomplete type 'VOID'}}
|
||
|
|
||
|
// C++11 disallows rvalue references.
|
||
|
|
||
|
template<int &R> struct lval_ref;
|
||
|
template<int &&R> struct rval_ref; // expected-warning 0-1{{extension}} expected-error {{non-type template parameter has rvalue reference type 'int &&'}}
|
||
|
|
||
|
// C++20 requires a structural type. In addition to the above cases, this allows:
|
||
|
|
||
|
// arbitrary scalar types; we generally include complex types in that list
|
||
|
template<_Complex float ci> struct ComplexFloat; // cxx17-error {{cannot have type '_Complex float' before C++20}}
|
||
|
template<_Complex int ci> struct ComplexInt; // cxx17-error {{cannot have type '_Complex int' before C++20}}
|
||
|
template<_ExtInt(42) ei> struct ExtInt;
|
||
|
|
||
|
// atomic types aren't scalar types
|
||
|
template<_Atomic float ci> struct AtomicFloat; // expected-error {{cannot have type '_Atomic(float)'}}
|
||
|
template<_Atomic int ci> struct AtomicInt; // expected-error {{cannot have type '_Atomic(int)'}}
|
||
|
|
||
|
// we allow vector types as an extension
|
||
|
typedef __attribute__((ext_vector_type(4))) int VI4;
|
||
|
typedef __attribute__((ext_vector_type(4))) float VF4;
|
||
|
template<VI4> struct VectorInt; // cxx17-error {{cannot have type 'VI4'}}
|
||
|
template<VF4> struct VectorFloat; // cxx17-error {{cannot have type 'VF4'}}
|
||
|
|
||
|
struct A2 {};
|
||
|
|
||
|
struct RRef {
|
||
|
int &&r; // cxx20-note 1+{{'RRef' is not a structural type because it has a non-static data member of rvalue reference type}}
|
||
|
};
|
||
|
|
||
|
// class types with all public members and bases, no mutable state, and no rvalue references.
|
||
|
struct B : A, public A2 {
|
||
|
int a;
|
||
|
private:
|
||
|
void f();
|
||
|
static int s;
|
||
|
public:
|
||
|
float g;
|
||
|
int &r = a;
|
||
|
void *p;
|
||
|
A2 a2;
|
||
|
RRef *ptr_to_bad;
|
||
|
RRef &ref_to_bad = *ptr_to_bad;
|
||
|
_Complex int ci;
|
||
|
_Complex float cf;
|
||
|
_ExtInt(42) ei;
|
||
|
VI4 vi4;
|
||
|
VF4 vf4;
|
||
|
};
|
||
|
|
||
|
template<B> struct ClassNTTP {}; // cxx17-error {{cannot have type 'B'}}
|
||
|
|
||
|
template<RRef> struct WithRRef {}; // cxx17-error {{cannot have type 'RRef'}}
|
||
|
// cxx20-error@-1 {{type 'RRef' of non-type template parameter is not a structural type}}
|
||
|
|
||
|
struct BadBase
|
||
|
: RRef {}; // cxx20-note {{'BadBase' is not a structural type because it has a base class of non-structural type 'RRef'}}
|
||
|
template<BadBase> struct WithBadBase {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|
||
|
|
||
|
struct BadField {
|
||
|
RRef r; // cxx20-note {{'BadField' is not a structural type because it has a non-static data member of non-structural type 'RRef'}}
|
||
|
};
|
||
|
template<BadField> struct WithBadField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|
||
|
|
||
|
struct BadFieldArray {
|
||
|
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'}}
|
||
|
};
|
||
|
template<BadFieldArray> struct WithBadFieldArray {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|
||
|
|
||
|
struct ProtectedBase
|
||
|
: protected A {}; // cxx20-note {{'ProtectedBase' is not a structural type because it has a base class that is not public}}
|
||
|
template<ProtectedBase> struct WithProtectedBase {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|
||
|
|
||
|
struct PrivateBase
|
||
|
: private A {}; // cxx20-note {{'PrivateBase' is not a structural type because it has a base class that is not public}}
|
||
|
template<PrivateBase> struct WithPrivateBase {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|
||
|
|
||
|
class Private2Base
|
||
|
: A {}; // cxx20-note {{'Private2Base' is not a structural type because it has a base class that is not public}}
|
||
|
template<Private2Base> struct WithPrivate2Base {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|
||
|
|
||
|
struct ProtectedField {
|
||
|
protected:
|
||
|
A r; // cxx20-note {{'ProtectedField' is not a structural type because it has a non-static data member that is not public}}
|
||
|
};
|
||
|
template<ProtectedField> struct WithProtectedField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|
||
|
|
||
|
struct PrivateField {
|
||
|
private:
|
||
|
A r; // cxx20-note {{'PrivateField' is not a structural type because it has a non-static data member that is not public}}
|
||
|
};
|
||
|
template<PrivateField> struct WithPrivateField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|
||
|
|
||
|
class Private2Field {
|
||
|
A r; // cxx20-note {{'Private2Field' is not a structural type because it has a non-static data member that is not public}}
|
||
|
};
|
||
|
template<Private2Field> struct WithPrivate2Field {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|
||
|
|
||
|
struct MutableField {
|
||
|
mutable int n; // cxx20-note {{'MutableField' is not a structural type because it has a mutable non-static data member}}
|
||
|
};
|
||
|
template<MutableField> struct WithMutableField {}; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|
||
|
|
||
|
template<typename T> struct BadExtType { T t; }; // cxx20-note 2{{has a non-static data member of non-structural type}}
|
||
|
template<BadExtType<_Atomic float> > struct AtomicFloatField; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|
||
|
template<BadExtType<_Atomic int> > struct AtomicInt; // cxx17-error {{cannot have type}} cxx20-error {{is not a structural type}}
|