1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s
// RUN: %clang_cc1 -verify=ref %s
constexpr void assert(bool C) {
if (C)
return;
// Invalid in constexpr.
(void)(1 / 0); // expected-warning {{undefined}} \
// ref-warning {{undefined}}
}
constexpr int i = 2;
constexpr float f = 1.0f;
static_assert(f == 1.0f, "");
constexpr float f2 = 1u * f;
static_assert(f2 == 1.0f, "");
constexpr float f3 = 1.5;
constexpr int i3 = f3;
static_assert(i3 == 1, "");
constexpr bool b3 = f3;
static_assert(b3, "");
static_assert(1.0f + 3u == 4, "");
static_assert(4.0f / 1.0f == 4, "");
static_assert(10.0f * false == 0, "");
constexpr float floats[] = {1.0f, 2.0f, 3.0f, 4.0f};
constexpr float m = 5.0f / 0.0f; // ref-error {{must be initialized by a constant expression}} \
// ref-note {{division by zero}} \
// expected-error {{must be initialized by a constant expression}} \
// expected-note {{division by zero}}
static_assert(~2.0f == 3, ""); // ref-error {{invalid argument type 'float' to unary expression}} \
// expected-error {{invalid argument type 'float' to unary expression}}
/// Initialized by a double.
constexpr float df = 0.0;
/// The other way around.
constexpr double fd = 0.0f;
static_assert(0.0f == -0.0f, "");
const int k = 3 * (1.0f / 3.0f);
static_assert(k == 1, "");
constexpr bool b = 1.0;
static_assert(b, "");
constexpr double db = true;
static_assert(db == 1.0, "");
constexpr float fa[] = {1.0f, 2.0, 1, false};
constexpr double da[] = {1.0f, 2.0, 1, false};
constexpr float fm = __FLT_MAX__;
constexpr int someInt = fm; // ref-error {{must be initialized by a constant expression}} \
// ref-note {{is outside the range of representable values}} \
// expected-error {{must be initialized by a constant expression}} \
// expected-note {{is outside the range of representable values}}
namespace compound {
constexpr float f1() {
float f = 0;
f += 3.0;
f -= 3.0f;
f += 1;
f /= 1;
f /= 1.0;
f *= f;
f *= 2.0;
return f;
}
static_assert(f1() == 2, "");
constexpr float f2() {
float f = __FLT_MAX__;
f += 1.0;
return f;
}
static_assert(f2() == __FLT_MAX__, "");
constexpr float ff() {
float a[] = {1,2};
int i = 0;
// RHS should be evaluated before LHS, so this should
// write to a[1];
a[i++] += ++i;
#if __cplusplus <= 201402L
// expected-warning@-2 {{multiple unsequenced modifications}} \
// ref-warning@-2 {{multiple unsequenced modifications}}
#endif
return a[1];
}
static_assert(ff() == 3, "");
}
namespace unary {
constexpr float a() {
float f = 0.0;
assert(++f == 1.0);
assert(f == 1.0);
++f;
f++;
assert(f == 3.0);
--f;
f--;
assert(f == 1.0);
return 1.0;
}
static_assert(a() == 1.0, "");
constexpr float b() {
float f = __FLT_MAX__;
f++;
return f;
}
static_assert(b() == __FLT_MAX__, "");
}
namespace ZeroInit {
template<typename FloatT>
struct A {
int a;
FloatT f;
};
constexpr A<float> a{12};
static_assert(a.f == 0.0f, "");
constexpr A<double> b{12};
static_assert(a.f == 0.0, "");
};
namespace LongDouble {
constexpr long double ld = 3.1425926539;
}
|