1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s 2 // RUN: %clang_cc1 -verify=ref %s 3 4 5 constexpr void assert(bool C) { 6 if (C) 7 return; 8 // Invalid in constexpr. 9 (void)(1 / 0); // expected-warning {{undefined}} \ 10 // ref-warning {{undefined}} 11 } 12 13 constexpr int i = 2; 14 constexpr float f = 1.0f; 15 static_assert(f == 1.0f, ""); 16 17 constexpr float f2 = 1u * f; 18 static_assert(f2 == 1.0f, ""); 19 20 constexpr float f3 = 1.5; 21 constexpr int i3 = f3; 22 static_assert(i3 == 1, ""); 23 24 constexpr bool b3 = f3; 25 static_assert(b3, ""); 26 27 28 static_assert(1.0f + 3u == 4, ""); 29 static_assert(4.0f / 1.0f == 4, ""); 30 static_assert(10.0f * false == 0, ""); 31 32 constexpr float floats[] = {1.0f, 2.0f, 3.0f, 4.0f}; 33 34 constexpr float m = 5.0f / 0.0f; // ref-error {{must be initialized by a constant expression}} \ 35 // ref-note {{division by zero}} \ 36 // expected-error {{must be initialized by a constant expression}} \ 37 // expected-note {{division by zero}} 38 39 static_assert(~2.0f == 3, ""); // ref-error {{invalid argument type 'float' to unary expression}} \ 40 // expected-error {{invalid argument type 'float' to unary expression}} 41 42 43 typedef int tdb[(long long)4e20]; //expected-error {{variable length}} \ 44 //ref-error {{variable length}} 45 46 /// Initialized by a double. 47 constexpr float df = 0.0; 48 /// The other way around. 49 constexpr double fd = 0.0f; 50 51 static_assert(0.0f == -0.0f, ""); 52 53 const int k = 3 * (1.0f / 3.0f); 54 static_assert(k == 1, ""); 55 56 constexpr bool b = 1.0; 57 static_assert(b, ""); 58 59 constexpr double db = true; 60 static_assert(db == 1.0, ""); 61 62 constexpr float fa[] = {1.0f, 2.0, 1, false}; 63 constexpr double da[] = {1.0f, 2.0, 1, false}; 64 65 constexpr float fm = __FLT_MAX__; 66 constexpr int someInt = fm; // ref-error {{must be initialized by a constant expression}} \ 67 // ref-note {{is outside the range of representable values}} \ 68 // expected-error {{must be initialized by a constant expression}} \ 69 // expected-note {{is outside the range of representable values}} 70 71 namespace compound { 72 constexpr float f1() { 73 float f = 0; 74 f += 3.0; 75 f -= 3.0f; 76 77 f += 1; 78 f /= 1; 79 f /= 1.0; 80 f *= f; 81 82 f *= 2.0; 83 return f; 84 } 85 static_assert(f1() == 2, ""); 86 87 constexpr float f2() { 88 float f = __FLT_MAX__; 89 f += 1.0; 90 return f; 91 } 92 static_assert(f2() == __FLT_MAX__, ""); 93 94 constexpr float ff() { 95 float a[] = {1,2}; 96 int i = 0; 97 98 // RHS should be evaluated before LHS, so this should 99 // write to a[1]; 100 a[i++] += ++i; 101 #if __cplusplus <= 201402L 102 // expected-warning@-2 {{multiple unsequenced modifications}} \ 103 // ref-warning@-2 {{multiple unsequenced modifications}} 104 #endif 105 106 return a[1]; 107 } 108 static_assert(ff() == 3, ""); 109 110 constexpr float intPlusDouble() { 111 int a = 0; 112 a += 2.0; 113 114 return a; 115 } 116 static_assert(intPlusDouble() == 2, ""); 117 118 constexpr double doublePlusInt() { 119 double a = 0.0; 120 a += 2; 121 122 return a; 123 } 124 static_assert(doublePlusInt() == 2, ""); 125 126 constexpr float boolPlusDouble() { 127 bool a = 0; 128 a += 1.0; 129 130 return a; 131 } 132 static_assert(boolPlusDouble(), ""); 133 134 constexpr bool doublePlusbool() { 135 double a = 0.0; 136 a += true; 137 138 return a; 139 } 140 static_assert(doublePlusbool() == 1.0, ""); 141 } 142 143 namespace unary { 144 constexpr float a() { 145 float f = 0.0; 146 assert(++f == 1.0); 147 assert(f == 1.0); 148 ++f; 149 f++; 150 assert(f == 3.0); 151 --f; 152 f--; 153 assert(f == 1.0); 154 return 1.0; 155 } 156 static_assert(a() == 1.0, ""); 157 158 constexpr float b() { 159 float f = __FLT_MAX__; 160 f++; 161 return f; 162 } 163 static_assert(b() == __FLT_MAX__, ""); 164 } 165 166 167 namespace ZeroInit { 168 template<typename FloatT> 169 struct A { 170 int a; 171 FloatT f; 172 }; 173 174 constexpr A<float> a{12}; 175 static_assert(a.f == 0.0f, ""); 176 177 constexpr A<double> b{12}; 178 static_assert(a.f == 0.0, ""); 179 }; 180 181 namespace LongDouble { 182 constexpr long double ld = 3.1425926539; 183 184 constexpr long double f() { 185 const long double L = __LDBL_MAX__; 186 187 return L; 188 }; 189 static_assert(f() == __LDBL_MAX__, ""); 190 191 #ifdef __FLOAT128__ 192 constexpr __float128 f128() { 193 const __float128 L = __LDBL_MAX__; 194 195 return L; 196 }; 197 static_assert(f128() == __LDBL_MAX__, ""); 198 #endif 199 } 200 201 namespace Compare { 202 constexpr float nan = __builtin_nan(""); 203 constexpr float inf = __builtin_inf(); 204 static_assert(!(nan == nan), ""); 205 static_assert(nan != nan, ""); 206 static_assert(!(inf < nan), ""); 207 static_assert(!(inf > nan), ""); 208 } 209 210 namespace nan { 211 constexpr double nan = __builtin_nan(""); 212 static_assert(nan); 213 214 constexpr double D1 = 1 + nan; // ref-error {{must be initialized by a constant expression}} \ 215 // ref-note {{produces a NaN}} \ 216 // expected-error {{must be initialized by a constant expression}} \ 217 // expected-note {{produces a NaN}} 218 219 constexpr double D2 = __builtin_inf() / __builtin_inf(); // ref-error {{must be initialized by a constant expression}} \ 220 // ref-note {{produces a NaN}} \ 221 // expected-error {{must be initialized by a constant expression}} \ 222 // expected-note {{produces a NaN}} 223 } 224