• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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