1 // RUN: %clang_cc1 -fcxx-exceptions -verify=expected,beforecxx14,beforecxx20,beforecxx2b -std=c++11 %s
2 // RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,beforecxx20,beforecxx2b -std=c++14 %s
3 // RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,aftercxx20,beforecxx2b -std=c++20  %s
4 // RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,aftercxx20 -std=c++2b %s
5 
6 namespace N {
7   typedef char C;
8 }
9 
10 namespace M {
11   typedef double D;
12 }
13 
14 struct NonLiteral { // expected-note 2{{no constexpr constructors}}
NonLiteralNonLiteral15   NonLiteral() {}
NonLiteralNonLiteral16   NonLiteral(int) {}
17 };
18 struct Literal {
LiteralLiteral19   constexpr Literal() {}
operator intLiteral20   operator int() const { return 0; }
21 };
22 
23 struct S {
24   virtual int ImplicitlyVirtual() const = 0; // beforecxx20-note {{overridden virtual function}}
25 };
26 struct SS : S {
27   int ImplicitlyVirtual() const;
28 };
29 
30 // The definition of a constexpr function shall satisfy the following
31 // constraints:
32 struct T : SS, NonLiteral {
33   constexpr T();
34   constexpr int f() const;
35 
36   //  - it shall not be virtual; [until C++20]
ExplicitlyVirtualT37   virtual constexpr int ExplicitlyVirtual() const { return 0; } // beforecxx20-error {{virtual function cannot be constexpr}}
38 
ImplicitlyVirtualT39   constexpr int ImplicitlyVirtual() const { return 0; } // beforecxx20-error {{virtual function cannot be constexpr}}
40 
41   virtual constexpr int OutOfLineVirtual() const; // beforecxx20-error {{virtual function cannot be constexpr}}
42 
43   //  - its return type shall be a literal type;
NonLiteralReturnT44   constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
VoidReturnT45   constexpr void VoidReturn() const { return; }                // beforecxx14-error {{constexpr function's return type 'void' is not a literal type}}
46   constexpr ~T();                                              // beforecxx20-error {{destructor cannot be declared constexpr}}
47 
48   typedef NonLiteral F() const;
49   constexpr F NonLiteralReturn2; // ok until definition
50 
51   //  - each of its parameter types shall be a literal type;
NonLiteralParamT52   constexpr int NonLiteralParam(NonLiteral) const { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
53   typedef int G(NonLiteral) const;
54   constexpr G NonLiteralParam2; // ok until definition
55 
56   //  - its function-body shall be = delete, = default,
57   constexpr int Deleted() const = delete;
58   // It's not possible for the function-body to legally be "= default" here
59   // (that is, for a non-constructor function) in C++11.
60   // Other than constructors, only the copy- and move-assignment operators and
61   // destructor can be defaulted. Destructors can't be constexpr since they
62   // don't have a literal return type. Defaulted assignment operators can't be
63   // constexpr since they can't be const.
64   constexpr T &operator=(const T &) = default; // beforecxx14-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} \
65                                                // beforecxx14-warning {{C++14}} \
66                                                // aftercxx14-error{{defaulted definition of copy assignment operator is not constexpr}}
67 };
68 
OutOfLineVirtual() const69 constexpr int T::OutOfLineVirtual() const { return 0; }
70 #if __cplusplus >= 201402L
71 struct T2 {
72   int n = 0;
73   constexpr T2 &operator=(const T2&) = default; // ok
74 };
75 struct T3 {
76   constexpr T3 &operator=(const T3 &) const = default; // beforecxx20-error {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}} \
77                                                        // aftercxx20-warning {{explicitly defaulted copy assignment operator is implicitly deleted}} \
78                                                        // aftercxx20-note {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
79 };
80 #endif
81 struct U {
82   constexpr U SelfReturn() const;
83   constexpr int SelfParam(U) const;
84 };
85 
86 struct V : virtual U { // expected-note {{here}}
FV87   constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
88 };
89 
90 //  or a compound-statememt that contains only [CXX11]
AllowedStmtsCXX11()91 constexpr int AllowedStmtsCXX11() {
92   //  - null statements
93   ;
94 
95   //  - static_assert-declarations
96   static_assert(true, "the impossible happened!");
97 
98   //  - typedef declarations and alias-declarations that do not define classes
99   //    or enumerations
100   typedef int I;
101   typedef struct S T;
102   using J = int;
103   using K = int[sizeof(I) + sizeof(J)];
104   // Note, the standard requires we reject this.
105   struct U;
106 
107   //  - using-declarations
108   using N::C;
109 
110   //  - using-directives
111   using namespace N;
112 
113   //  - and exactly one return statement
114   return sizeof(K) + sizeof(C) + sizeof(K);
115 }
116 
117 //  or a compound-statement that does not contain [C++14]
DisallowedStmtsCXX14_1(bool b)118 constexpr int DisallowedStmtsCXX14_1(bool b) {
119   //  - an asm-definition
120   if (b)
121     asm("int3"); // beforecxx20-warning {{use of this statement in a constexpr function is a C++20 extension}}
122   return 0;
123 }
DisallowedStmtsCXX14_2()124 constexpr int DisallowedStmtsCXX14_2() {
125   return 0; // beforecxx14-note {{previous}}
126   //  - a goto statement
127   goto x; // beforecxx2b-warning {{use of this statement in a constexpr function is a C++2b extension}}
128   x:;
129     return 0; // beforecxx14-warning {{multiple return}}
130 }
DisallowedStmtsCXX14_2_1()131 constexpr int DisallowedStmtsCXX14_2_1() {
132 merp: // beforecxx2b-warning {{use of this statement in a constexpr function is a C++2b extension}}
133   return 0;
134 }
DisallowedStmtsCXX14_3()135 constexpr int DisallowedStmtsCXX14_3() {
136   //  - a try-block,
137   try {  }  // beforecxx20-warning {{use of this statement in a constexpr function is a C++20 extension}}
138   catch (...) {}
139   return 0;
140 }
DisallowedStmtsCXX14_4()141 constexpr int DisallowedStmtsCXX14_4() {
142   //  - a definition of a variable of non-literal type
143   return 0;
144   NonLiteral nl; // beforecxx2b-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \
145                  // beforecxx2b-note@14  {{'NonLiteral' is not literal}}
146 }
147 
DisallowedStmtsCXX14_5()148 constexpr int DisallowedStmtsCXX14_5() {
149   return 0;
150   //  - a definition of a variable of static storage duration
151   static constexpr int n = 123; // beforecxx2b-warning {{definition of a static variable in a constexpr function is a C++2b extension}} \
152                                //  beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
153 }
154 
DisallowedStmtsCXX14_6()155 constexpr int DisallowedStmtsCXX14_6() {
156   //  - a definition of a variable of thread storage duration
157   return 0;
158   thread_local constexpr int n = 123; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}} \
159                                       // beforecxx2b-warning {{definition of a thread_local variable in a constexpr function is a C++2b extension}}
160 }
DisallowedStmtsCXX14_7()161 constexpr int DisallowedStmtsCXX14_7() {
162   //  - a definition of a variable for which no initialization is performed
163   return 0;
164   int n; // beforecxx20-warning {{uninitialized variable in a constexpr function}}
165 }
166 
ForStmt()167 constexpr int ForStmt() {
168   for (int n = 0; n < 10; ++n) {} // beforecxx14-error {{statement not allowed in constexpr function}}
169     return 0;
170 }
171 
VarDecl()172 constexpr int VarDecl() {
173   int a = 0; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
174   return 0;
175 }
ConstexprVarDecl()176 constexpr int ConstexprVarDecl() {
177   constexpr int a = 0; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
178   return 0;
179 }
VarWithCtorDecl()180 constexpr int VarWithCtorDecl() {
181   Literal a; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
182   return 0;
183 }
184 
185 NonLiteral nl;
ExternNonLiteralVarDecl()186 constexpr NonLiteral &ExternNonLiteralVarDecl() {
187   extern NonLiteral nl; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
188   return nl;
189 }
190 static_assert(&ExternNonLiteralVarDecl() == &nl, "");
191 
FuncDecl()192 constexpr int FuncDecl() {
193   constexpr int ForwardDecl(int); // beforecxx14-warning {{use of this statement in a constexpr function is a C++14 extension}}
194   return ForwardDecl(42);
195 }
196 
ClassDecl1()197 constexpr int ClassDecl1() {
198   typedef struct {} S1; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}}
199   return 0;
200 }
201 
ClassDecl2()202 constexpr int ClassDecl2() {
203   using S2 = struct {}; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}}
204   return 0;
205 }
206 
ClassDecl3()207 constexpr int ClassDecl3() {
208   struct S3 {}; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}}
209   return 0;
210 }
211 
NoReturn()212 constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
MultiReturn()213 constexpr int MultiReturn() {
214   return 0; // beforecxx14-note {{return statement}}
215   return 0; // beforecxx14-warning {{multiple return statements in constexpr function}}
216 }
217 
218 //  - every constructor call and implicit conversion used in initializing the
219 //    return value shall be one of those allowed in a constant expression.
220 //
221 // We implement the proposed resolution of DR1364 and ignore this bullet.
222 // However, we implement the spirit of the check as part of the p5 checking that
223 // a constexpr function must be able to produce a constant expression.
224 namespace DR1364 {
f(int k)225   constexpr int f(int k) {
226     return k; // ok, even though lvalue-to-rvalue conversion of a function
227               // parameter is not allowed in a constant expression.
228   }
229   int kGlobal; // expected-note {{here}}
f()230   constexpr int f() { // expected-error {{constexpr function never produces a constant expression}}
231     return kGlobal;   // expected-note {{read of non-const}}
232   }
233 }
234 
235 namespace rdar13584715 {
236   typedef __PTRDIFF_TYPE__ ptrdiff_t;
237 
238   template<typename T> struct X {
valuerdar13584715::X239     static T value() {};
240   };
241 
foo(ptrdiff_t id)242   void foo(ptrdiff_t id) {
243     switch (id) {
244     case reinterpret_cast<ptrdiff_t>(&X<long>::value):  // expected-error{{case value is not a constant expression}} \
245       // expected-note{{reinterpret_cast is not allowed in a constant expression}}
246       break;
247     }
248   }
249 }
250 
251 namespace std_example {
square(int x)252   constexpr int square(int x) {
253     return x * x;
254   }
long_max()255   constexpr long long_max() {
256     return 2147483647;
257   }
abs(int x)258   constexpr int abs(int x) {
259     if (x < 0) // beforecxx14-warning {{C++14}}
260       x = -x;
261     return x;
262   }
first(int n)263   constexpr int first(int n) {
264     return 0;
265     static int value = n; // beforecxx2b-warning {{definition of a static variable in a constexpr function is a C++2b extension}} \
266                           // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
267   }
uninit()268   constexpr int uninit() {
269     int a; // beforecxx20-warning {{uninitialized}}
270     return a;
271   }
prev(int x)272   constexpr int prev(int x) { // beforecxx14-error {{never produces a constant expression}}
273     return --x;               // beforecxx14-note {{subexpression}}
274   }
275 
g(int x,int n)276   constexpr int g(int x, int n) {
277     int r = 1; // beforecxx14-warning{{C++14}}
278     while (--n > 0) // beforecxx14-error {{statement not allowed in constexpr function}}
279       r *= x;
280     return r;
281   }
282 }
283