• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++1y-extensions %s
2 // RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++1y -DCXX1Y %s
3 
4 namespace N {
5   typedef char C;
6 }
7 
8 namespace M {
9   typedef double D;
10 }
11 
12 struct NonLiteral { // expected-note 3{{no constexpr constructors}}
NonLiteralNonLiteral13   NonLiteral() {}
NonLiteralNonLiteral14   NonLiteral(int) {}
15 };
16 struct Literal {
LiteralLiteral17   constexpr Literal() {}
operator intLiteral18   operator int() const { return 0; }
19 };
20 
21 struct S {
22   virtual int ImplicitlyVirtual() const = 0; // expected-note {{overridden virtual function}}
23 };
24 struct SS : S {
25   int ImplicitlyVirtual() const;
26 };
27 
28 // The definition of a constexpr function shall satisfy the following
29 // constraints:
30 struct T : SS, NonLiteral {
31   constexpr T();
32   constexpr int f() const;
33 
34   //  - it shall not be virtual;
ExplicitlyVirtualT35   virtual constexpr int ExplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
36 
ImplicitlyVirtualT37   constexpr int ImplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
38 
39   virtual constexpr int OutOfLineVirtual() const; // expected-error {{virtual function cannot be constexpr}}
40 
41   //  - its return type shall be a literal type;
NonLiteralReturnT42   constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
VoidReturnT43   constexpr void VoidReturn() const { return; }
44 #ifndef CXX1Y
45   // expected-error@-2 {{constexpr function's return type 'void' is not a literal type}}
46 #endif
47   constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}}
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;
65 #ifndef CXX1Y
66   // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
67   // expected-warning@-3 {{C++14}}
68 #else
69   // expected-error@-5 {{defaulted definition of copy assignment operator is not constexpr}}
70 #endif
71 };
72 
OutOfLineVirtual() const73 constexpr int T::OutOfLineVirtual() const { return 0; }
74 #ifdef CXX1Y
75 struct T2 {
76   int n = 0;
77   constexpr T2 &operator=(const T2&) = default; // ok
78 };
79 struct T3 {
80   constexpr T3 &operator=(const T3&) const = default;
81   // expected-error@-1 {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}}
82 };
83 #endif
84 struct U {
85   constexpr U SelfReturn() const;
86   constexpr int SelfParam(U) const;
87 };
88 
89 struct V : virtual U { // expected-note {{here}}
FV90   constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
91 };
92 
93 //  or a compound-statememt that contains only [CXX11]
AllowedStmtsCXX11()94 constexpr int AllowedStmtsCXX11() {
95   //  - null statements
96   ;
97 
98   //  - static_assert-declarations
99   static_assert(true, "the impossible happened!");
100 
101   //  - typedef declarations and alias-declarations that do not define classes
102   //    or enumerations
103   typedef int I;
104   typedef struct S T;
105   using J = int;
106   using K = int[sizeof(I) + sizeof(J)];
107   // Note, the standard requires we reject this.
108   struct U;
109 
110   //  - using-declarations
111   using N::C;
112 
113   //  - using-directives
114   using namespace N;
115 
116   //  - and exactly one return statement
117   return sizeof(K) + sizeof(C) + sizeof(K);
118 }
119 
120 //  or a compound-statement that does not contain [CXX1Y]
DisallowedStmtsCXX1Y_1()121 constexpr int DisallowedStmtsCXX1Y_1() {
122   //  - an asm-definition
123   asm("int3"); // expected-error {{statement not allowed in constexpr function}}
124   return 0;
125 }
DisallowedStmtsCXX1Y_2()126 constexpr int DisallowedStmtsCXX1Y_2() {
127   //  - a goto statement
128   goto x; // expected-error {{statement not allowed in constexpr function}}
129 x:
130   return 0;
131 }
DisallowedStmtsCXX1Y_3()132 constexpr int DisallowedStmtsCXX1Y_3() {
133   //  - a try-block,
134   try {} catch (...) {} // expected-error {{statement not allowed in constexpr function}}
135   return 0;
136 }
DisallowedStmtsCXX1Y_4()137 constexpr int DisallowedStmtsCXX1Y_4() {
138   //  - a definition of a variable of non-literal type
139   NonLiteral nl; // expected-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function}}
140   return 0;
141 }
DisallowedStmtsCXX1Y_5()142 constexpr int DisallowedStmtsCXX1Y_5() {
143   //  - a definition of a variable of static storage duration
144   static constexpr int n = 123; // expected-error {{static variable not permitted in a constexpr function}}
145   return n;
146 }
DisallowedStmtsCXX1Y_6()147 constexpr int DisallowedStmtsCXX1Y_6() {
148   //  - a definition of a variable of thread storage duration
149   thread_local constexpr int n = 123; // expected-error {{thread_local variable not permitted in a constexpr function}}
150   return n;
151 }
DisallowedStmtsCXX1Y_7()152 constexpr int DisallowedStmtsCXX1Y_7() {
153   //  - a definition of a variable for which no initialization is performed
154   int n; // expected-error {{variables defined in a constexpr function must be initialized}}
155   return 0;
156 }
157 
ForStmt()158 constexpr int ForStmt() {
159   for (int n = 0; n < 10; ++n)
160 #ifndef CXX1Y
161   // expected-error@-2 {{statement not allowed in constexpr function}}
162 #endif
163     return 0;
164 }
VarDecl()165 constexpr int VarDecl() {
166   int a = 0;
167 #ifndef CXX1Y
168   // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
169 #endif
170   return 0;
171 }
ConstexprVarDecl()172 constexpr int ConstexprVarDecl() {
173   constexpr int a = 0;
174 #ifndef CXX1Y
175   // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
176 #endif
177   return 0;
178 }
VarWithCtorDecl()179 constexpr int VarWithCtorDecl() {
180   Literal a;
181 #ifndef CXX1Y
182   // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
183 #endif
184   return 0;
185 }
186 NonLiteral nl;
ExternNonLiteralVarDecl()187 constexpr NonLiteral &ExternNonLiteralVarDecl() {
188   extern NonLiteral nl;
189 #ifndef CXX1Y
190   // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
191 #endif
192   return nl;
193 }
194 static_assert(&ExternNonLiteralVarDecl() == &nl, "");
FuncDecl()195 constexpr int FuncDecl() {
196   constexpr int ForwardDecl(int);
197 #ifndef CXX1Y
198   // expected-error@-2 {{use of this statement in a constexpr function is a C++14 extension}}
199 #endif
200   return ForwardDecl(42);
201 }
ClassDecl1()202 constexpr int ClassDecl1() {
203   typedef struct { } S1;
204 #ifndef CXX1Y
205   // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}}
206 #endif
207   return 0;
208 }
ClassDecl2()209 constexpr int ClassDecl2() {
210   using S2 = struct { };
211 #ifndef CXX1Y
212   // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}}
213 #endif
214   return 0;
215 }
ClassDecl3()216 constexpr int ClassDecl3() {
217   struct S3 { };
218 #ifndef CXX1Y
219   // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}}
220 #endif
221   return 0;
222 }
NoReturn()223 constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
MultiReturn()224 constexpr int MultiReturn() {
225   return 0;
226   return 0;
227 #ifndef CXX1Y
228   // expected-error@-2 {{multiple return statements in constexpr function}}
229   // expected-note@-4 {{return statement}}
230 #endif
231 }
232 
233 //  - every constructor call and implicit conversion used in initializing the
234 //    return value shall be one of those allowed in a constant expression.
235 //
236 // We implement the proposed resolution of DR1364 and ignore this bullet.
237 // However, we implement the spirit of the check as part of the p5 checking that
238 // a constexpr function must be able to produce a constant expression.
239 namespace DR1364 {
f(int k)240   constexpr int f(int k) {
241     return k; // ok, even though lvalue-to-rvalue conversion of a function
242               // parameter is not allowed in a constant expression.
243   }
244   int kGlobal; // expected-note {{here}}
f()245   constexpr int f() { // expected-error {{constexpr function never produces a constant expression}}
246     return kGlobal; // expected-note {{read of non-const}}
247   }
248 }
249 
250 namespace rdar13584715 {
251   typedef __PTRDIFF_TYPE__ ptrdiff_t;
252 
253   template<typename T> struct X {
valuerdar13584715::X254     static T value() {};
255   };
256 
foo(ptrdiff_t id)257   void foo(ptrdiff_t id) {
258     switch (id) {
259     case reinterpret_cast<ptrdiff_t>(&X<long>::value):  // expected-error{{case value is not a constant expression}} \
260       // expected-note{{reinterpret_cast is not allowed in a constant expression}}
261       break;
262     }
263   }
264 }
265 
266 namespace std_example {
square(int x)267   constexpr int square(int x) {
268     return x * x;
269   }
long_max()270   constexpr long long_max() {
271     return 2147483647;
272   }
abs(int x)273   constexpr int abs(int x) {
274     if (x < 0)
275 #ifndef CXX1Y
276       // expected-error@-2 {{C++14}}
277 #endif
278       x = -x;
279     return x;
280   }
first(int n)281   constexpr int first(int n) {
282     static int value = n; // expected-error {{static variable not permitted}}
283     return value;
284   }
uninit()285   constexpr int uninit() {
286     int a; // expected-error {{must be initialized}}
287     return a;
288   }
prev(int x)289   constexpr int prev(int x) {
290     return --x;
291   }
292 #ifndef CXX1Y
293   // expected-error@-4 {{never produces a constant expression}}
294   // expected-note@-4 {{subexpression}}
295 #endif
g(int x,int n)296   constexpr int g(int x, int n) {
297     int r = 1;
298     while (--n > 0) r *= x;
299     return r;
300   }
301 #ifndef CXX1Y
302     // expected-error@-5 {{C++14}}
303     // expected-error@-5 {{statement not allowed}}
304 #endif
305 }
306