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