2023-01-25 14:51:16 +01:00
|
|
|
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s
|
|
|
|
// RUN: %clang_cc1 -verify=ref %s
|
|
|
|
|
2023-04-21 10:41:40 +02:00
|
|
|
|
|
|
|
constexpr void assert(bool C) {
|
|
|
|
if (C)
|
|
|
|
return;
|
|
|
|
// Invalid in constexpr.
|
|
|
|
(void)(1 / 0); // expected-warning {{undefined}} \
|
|
|
|
// ref-warning {{undefined}}
|
|
|
|
}
|
|
|
|
|
2023-01-25 14:51:16 +01:00
|
|
|
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;
|
2023-01-25 15:19:17 +01:00
|
|
|
static_assert(i3 == 1, "");
|
2023-01-25 14:51:16 +01:00
|
|
|
|
|
|
|
constexpr bool b3 = f3;
|
2023-01-25 15:19:17 +01:00
|
|
|
static_assert(b3, "");
|
2023-01-25 14:51:16 +01:00
|
|
|
|
|
|
|
|
|
|
|
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}}
|
|
|
|
|
2023-12-11 17:25:03 +01:00
|
|
|
|
|
|
|
typedef int tdb[(long long)4e20]; //expected-error {{variable length}} \
|
|
|
|
//ref-error {{variable length}}
|
|
|
|
|
2023-01-25 14:51:16 +01:00
|
|
|
/// 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}}
|
2022-12-20 10:19:56 +01:00
|
|
|
|
|
|
|
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__, "");
|
2023-04-30 16:20:20 +02:00
|
|
|
|
|
|
|
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;
|
2023-07-20 16:38:32 +02:00
|
|
|
#if __cplusplus <= 201402L
|
|
|
|
// expected-warning@-2 {{multiple unsequenced modifications}} \
|
|
|
|
// ref-warning@-2 {{multiple unsequenced modifications}}
|
|
|
|
#endif
|
2023-04-30 16:20:20 +02:00
|
|
|
|
|
|
|
return a[1];
|
|
|
|
}
|
|
|
|
static_assert(ff() == 3, "");
|
2023-08-10 12:01:08 +02:00
|
|
|
|
|
|
|
constexpr float intPlusDouble() {
|
|
|
|
int a = 0;
|
|
|
|
a += 2.0;
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
static_assert(intPlusDouble() == 2, "");
|
|
|
|
|
|
|
|
constexpr double doublePlusInt() {
|
|
|
|
double a = 0.0;
|
|
|
|
a += 2;
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
static_assert(doublePlusInt() == 2, "");
|
|
|
|
|
|
|
|
constexpr float boolPlusDouble() {
|
|
|
|
bool a = 0;
|
|
|
|
a += 1.0;
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
static_assert(boolPlusDouble(), "");
|
|
|
|
|
|
|
|
constexpr bool doublePlusbool() {
|
|
|
|
double a = 0.0;
|
|
|
|
a += true;
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
static_assert(doublePlusbool() == 1.0, "");
|
2022-12-20 10:19:56 +01:00
|
|
|
}
|
2023-03-24 08:33:59 +01:00
|
|
|
|
2023-04-21 10:41:40 +02:00
|
|
|
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;
|
|
|
|
}
|
2023-05-04 09:09:57 +02:00
|
|
|
static_assert(a() == 1.0, "");
|
2023-04-21 10:41:40 +02:00
|
|
|
|
|
|
|
constexpr float b() {
|
|
|
|
float f = __FLT_MAX__;
|
|
|
|
f++;
|
|
|
|
return f;
|
|
|
|
}
|
2023-05-04 09:09:57 +02:00
|
|
|
static_assert(b() == __FLT_MAX__, "");
|
2023-04-21 10:41:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-03-24 08:33:59 +01:00
|
|
|
namespace ZeroInit {
|
|
|
|
template<typename FloatT>
|
|
|
|
struct A {
|
|
|
|
int a;
|
|
|
|
FloatT f;
|
|
|
|
};
|
|
|
|
|
|
|
|
constexpr A<float> a{12};
|
2023-04-06 12:03:45 +02:00
|
|
|
static_assert(a.f == 0.0f, "");
|
2023-03-24 08:33:59 +01:00
|
|
|
|
|
|
|
constexpr A<double> b{12};
|
2023-04-06 12:03:45 +02:00
|
|
|
static_assert(a.f == 0.0, "");
|
2023-03-24 08:33:59 +01:00
|
|
|
};
|
2023-07-11 09:47:03 +02:00
|
|
|
|
|
|
|
namespace LongDouble {
|
|
|
|
constexpr long double ld = 3.1425926539;
|
2023-07-13 11:17:56 +02:00
|
|
|
|
|
|
|
constexpr long double f() {
|
|
|
|
const long double L = __LDBL_MAX__;
|
|
|
|
|
|
|
|
return L;
|
|
|
|
};
|
2023-08-21 20:28:39 -07:00
|
|
|
static_assert(f() == __LDBL_MAX__, "");
|
2023-07-13 11:17:56 +02:00
|
|
|
|
|
|
|
#ifdef __FLOAT128__
|
|
|
|
constexpr __float128 f128() {
|
|
|
|
const __float128 L = __LDBL_MAX__;
|
|
|
|
|
|
|
|
return L;
|
|
|
|
};
|
2023-08-21 20:28:39 -07:00
|
|
|
static_assert(f128() == __LDBL_MAX__, "");
|
2023-07-13 11:17:56 +02:00
|
|
|
#endif
|
2023-07-11 09:47:03 +02:00
|
|
|
}
|
2023-07-16 23:33:30 +02:00
|
|
|
|
|
|
|
namespace Compare {
|
|
|
|
constexpr float nan = __builtin_nan("");
|
|
|
|
constexpr float inf = __builtin_inf();
|
|
|
|
static_assert(!(nan == nan), "");
|
|
|
|
static_assert(nan != nan, "");
|
|
|
|
static_assert(!(inf < nan), "");
|
|
|
|
static_assert(!(inf > nan), "");
|
|
|
|
}
|
2023-07-28 08:07:51 +02:00
|
|
|
|
|
|
|
namespace nan {
|
|
|
|
constexpr double nan = __builtin_nan("");
|
|
|
|
static_assert(nan);
|
|
|
|
|
|
|
|
constexpr double D1 = 1 + nan; // ref-error {{must be initialized by a constant expression}} \
|
|
|
|
// ref-note {{produces a NaN}} \
|
|
|
|
// expected-error {{must be initialized by a constant expression}} \
|
|
|
|
// expected-note {{produces a NaN}}
|
|
|
|
|
|
|
|
constexpr double D2 = __builtin_inf() / __builtin_inf(); // ref-error {{must be initialized by a constant expression}} \
|
|
|
|
// ref-note {{produces a NaN}} \
|
|
|
|
// expected-error {{must be initialized by a constant expression}} \
|
|
|
|
// expected-note {{produces a NaN}}
|
|
|
|
}
|