xref: /llvm-project/clang/test/AST/ByteCode/cxx11.cpp (revision 58fa55c04baaaa645a0bf9e265154b7ea7caf0d8)
1 // RUN: %clang_cc1 -triple x86_64-linux -fexperimental-new-constant-interpreter -verify=both,expected -std=c++11 %s
2 // RUN: %clang_cc1 -triple x86_64-linux -verify=both,ref -std=c++11 %s
3 
4 namespace IntOrEnum {
5   const int k = 0;
6   const int &p = k;
7   template<int n> struct S {};
8   S<p> s;
9 }
10 
11 const int cval = 2;
12 template <int> struct C{};
13 template struct C<cval>;
14 
15 
16 /// FIXME: This example does not get properly diagnosed in the new interpreter.
17 extern const int recurse1;
18 const int recurse2 = recurse1; // both-note {{here}}
19 const int recurse1 = 1;
20 int array1[recurse1];
21 int array2[recurse2]; // both-warning {{variable length arrays in C++}} \
22                       // both-note {{initializer of 'recurse2' is not a constant expression}} \
23                       // expected-error {{variable length array declaration not allowed at file scope}} \
24                       // ref-warning {{variable length array folded to constant array as an extension}}
25 
26 struct S {
27   int m;
28 };
29 constexpr S s = { 5 };
30 constexpr const int *p = &s.m + 1;
31 
32 constexpr const int *np2 = &(*(int(*)[4])nullptr)[0]; // ok
33 
34 constexpr int preDec(int x) { // both-error {{never produces a constant expression}}
35   return --x;                 // both-note {{subexpression}}
36 }
37 
38 constexpr int postDec(int x) { // both-error {{never produces a constant expression}}
39   return x--;                  // both-note {{subexpression}}
40 }
41 
42 constexpr int preInc(int x) { // both-error {{never produces a constant expression}}
43   return ++x;                  // both-note {{subexpression}}
44 }
45 
46 constexpr int postInc(int x) { // both-error {{never produces a constant expression}}
47   return x++;                  // both-note {{subexpression}}
48 }
49 
50 
51 namespace ReferenceToConst {
52   template<int n> struct S; // both-note 1{{here}}
53   struct LiteralType {
54     constexpr LiteralType(int n) : n(n) {}
55     int n;
56   };
57   template<int n> struct T {
58     T() {
59       static const int ki = 42;
60       const int &i2 = ki;
61       typename S<i2>::T check5; // both-error {{undefined template}}
62     }
63   };
64 }
65 
66 
67 
68 namespace GH50055 {
69 // Enums without fixed underlying type
70 enum E1 {e11=-4, e12=4};
71 enum E2 {e21=0, e22=4};
72 enum E3 {e31=-4, e32=1024};
73 enum E4 {e41=0};
74 // Empty but as-if it had a single enumerator with value 0
75 enum EEmpty {};
76 
77 // Enum with fixed underlying type because the underlying type is explicitly specified
78 enum EFixed : int {efixed1=-4, efixed2=4};
79 // Enum with fixed underlying type because it is scoped
80 enum class EScoped {escoped1=-4, escoped2=4};
81 
82 enum EMaxInt {emaxint1=-1, emaxint2=__INT_MAX__};
83 
84 enum NumberType {};
85 
86 E2 testDefaultArgForParam(E2 e2Param = (E2)-1) { // ok, not a constant expression context
87   E2 e2LocalInit = e2Param; // ok, not a constant expression context
88   return e2LocalInit;
89 }
90 
91 // #include <enum-constexpr-conversion-system-header.h>
92 
93 void testValueInRangeOfEnumerationValues() {
94   constexpr E1 x1 = static_cast<E1>(-8);
95   constexpr E1 x2 = static_cast<E1>(8);
96   // both-error@-1 {{constexpr variable 'x2' must be initialized by a constant expression}}
97   // both-note@-2 {{integer value 8 is outside the valid range of values [-8, 7] for the enumeration type 'E1'}}
98   E1 x2b = static_cast<E1>(8); // ok, not a constant expression context
99 
100   constexpr E2 x3 = static_cast<E2>(-8);
101   // both-error@-1 {{constexpr variable 'x3' must be initialized by a constant expression}}
102   // both-note@-2 {{integer value -8 is outside the valid range of values [0, 7] for the enumeration type 'E2'}}
103   constexpr E2 x4 = static_cast<E2>(0);
104   constexpr E2 x5 = static_cast<E2>(8);
105   // both-error@-1 {{constexpr variable 'x5' must be initialized by a constant expression}}
106   // both-note@-2 {{integer value 8 is outside the valid range of values [0, 7] for the enumeration type 'E2'}}
107 
108   constexpr E3 x6 = static_cast<E3>(-2048);
109   constexpr E3 x7 = static_cast<E3>(-8);
110   constexpr E3 x8 = static_cast<E3>(0);
111   constexpr E3 x9 = static_cast<E3>(8);
112   constexpr E3 x10 = static_cast<E3>(2048);
113   // both-error@-1 {{constexpr variable 'x10' must be initialized by a constant expression}}
114   // both-note@-2 {{integer value 2048 is outside the valid range of values [-2048, 2047] for the enumeration type 'E3'}}
115 
116   constexpr E4 x11 = static_cast<E4>(0);
117   constexpr E4 x12 = static_cast<E4>(1);
118   constexpr E4 x13 = static_cast<E4>(2);
119   // both-error@-1 {{constexpr variable 'x13' must be initialized by a constant expression}}
120   // both-note@-2 {{integer value 2 is outside the valid range of values [0, 1] for the enumeration type 'E4'}}
121 
122   constexpr EEmpty x14 = static_cast<EEmpty>(0);
123   constexpr EEmpty x15 = static_cast<EEmpty>(1);
124   constexpr EEmpty x16 = static_cast<EEmpty>(2);
125   // both-error@-1 {{constexpr variable 'x16' must be initialized by a constant expression}}
126   // both-note@-2 {{integer value 2 is outside the valid range of values [0, 1] for the enumeration type 'EEmpty'}}
127 
128   constexpr EFixed x17 = static_cast<EFixed>(100);
129   constexpr EScoped x18 = static_cast<EScoped>(100);
130 
131   constexpr EMaxInt x19 = static_cast<EMaxInt>(__INT_MAX__-1);
132   constexpr EMaxInt x20 = static_cast<EMaxInt>((long)__INT_MAX__+1);
133   // both-error@-1 {{constexpr variable 'x20' must be initialized by a constant expression}}
134   // both-note@-2 {{integer value 2147483648 is outside the valid range of values [-2147483648, 2147483647] for the enumeration type 'EMaxInt'}}
135 
136   const NumberType neg_one = (NumberType) ((NumberType) 0 - (NumberType) 1); // ok, not a constant expression context
137 }
138 
139 template<class T, unsigned size> struct Bitfield {
140   static constexpr T max = static_cast<T>((1 << size) - 1);
141   // both-error@-1 {{constexpr variable 'max' must be initialized by a constant expression}}
142   // both-note@-2 {{integer value 15 is outside the valid range of values [0, 7] for the enumeration type 'E2'}}
143 };
144 
145 void testValueInRangeOfEnumerationValuesViaTemplate() {
146   Bitfield<E2, 3> good;
147   Bitfield<E2, 4> bad; // both-note {{in instantiation}}
148 }
149 
150 enum SortOrder {
151   AscendingOrder,
152   DescendingOrder
153 };
154 
155 class A {
156   static void f(SortOrder order);
157 };
158 
159 void A::f(SortOrder order) {
160   if (order == SortOrder(-1)) // ok, not a constant expression context
161     return;
162 }
163 }
164 
165 namespace FinalLtorDiags {
166   template<int*> struct A {}; // both-note {{template parameter is declared here}}
167   int k;
168   int *q = &k; // both-note {{declared here}}
169   A<q> c; // both-error {{non-type template argument of type 'int *' is not a constant expression}} \
170           // both-note {{read of non-constexpr variable 'q' is not allowed in a constant expression}}
171 }
172 
173 void lambdas() {
174   int d;
175   int a9[1] = {[d = 0] = 1}; // both-error {{not an integral constant expression}}
176 }
177 
178 
179 namespace InitLinkToRVO {
180   struct A {
181     int y = 3;
182     int z = 1 + y;
183   };
184 
185   constexpr A make() { return A {}; }
186   static_assert(make().z == 4, "");
187 }
188