227 lines · cpp
1// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s2// RUN: %clang_cc1 -verify=ref %s3 4 5constexpr 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 13constexpr int i = 2;14constexpr float f = 1.0f;15static_assert(f == 1.0f, "");16 17constexpr float f2 = 1u * f;18static_assert(f2 == 1.0f, "");19 20constexpr float f3 = 1.5;21constexpr int i3 = f3;22static_assert(i3 == 1, "");23 24constexpr bool b3 = f3;25static_assert(b3, "");26 27 28static_assert(1.0f + 3u == 4, "");29static_assert(4.0f / 1.0f == 4, "");30static_assert(10.0f * false == 0, "");31 32constexpr float floats[] = {1.0f, 2.0f, 3.0f, 4.0f};33 34constexpr 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 39static_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 43typedef int tdb[(long long)4e20]; //expected-error {{variable length}} \44 //ref-error {{variable length}}45 46/// Initialized by a double.47constexpr float df = 0.0;48/// The other way around.49constexpr double fd = 0.0f;50 51static_assert(0.0f == -0.0f, "");52 53const int k = 3 * (1.0f / 3.0f);54static_assert(k == 1, "");55 56constexpr bool b = 1.0;57static_assert(b, "");58 59constexpr double db = true;60static_assert(db == 1.0, "");61 62constexpr float fa[] = {1.0f, 2.0, 1, false};63constexpr double da[] = {1.0f, 2.0, 1, false};64 65constexpr float fm = __FLT_MAX__;66constexpr 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 71namespace 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 should99 // write to a[1];100 a[i++] += ++i;101#if __cplusplus <= 201402L102 // expected-warning@-2 {{multiple unsequenced modifications}} \103 // ref-warning@-2 {{multiple unsequenced modifications}}104#endif105 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 143namespace 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 167namespace 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(b.f == 0.0, "");179 180 constexpr A<_Atomic(float)> c{12};181 static_assert(c.f == 0.0, "");182};183 184namespace LongDouble {185 constexpr long double ld = 3.1425926539;186 187 constexpr long double f() {188 const long double L = __LDBL_MAX__;189 190 return L;191 };192 static_assert(f() == __LDBL_MAX__, "");193 194#ifdef __FLOAT128__195 constexpr __float128 f128() {196 const __float128 L = __LDBL_MAX__;197 198 return L;199 };200 static_assert(f128() == __LDBL_MAX__, "");201#endif202}203 204namespace Compare {205 constexpr float nan = __builtin_nan("");206 constexpr float inf = __builtin_inf();207 static_assert(!(nan == nan), "");208 static_assert(nan != nan, "");209 static_assert(!(inf < nan), "");210 static_assert(!(inf > nan), "");211}212 213namespace nan {214 constexpr double nan = __builtin_nan("");215 static_assert(nan);216 217 constexpr double D1 = 1 + nan; // ref-error {{must be initialized by a constant expression}} \218 // ref-note {{produces a NaN}} \219 // expected-error {{must be initialized by a constant expression}} \220 // expected-note {{produces a NaN}}221 222 constexpr double D2 = __builtin_inf() / __builtin_inf(); // ref-error {{must be initialized by a constant expression}} \223 // ref-note {{produces a NaN}} \224 // expected-error {{must be initialized by a constant expression}} \225 // expected-note {{produces a NaN}}226}227