Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / AST / Interp / floats.cpp
blobe17167f5bf6dbbf66da24ec3edd3704fded2c4d1
1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s
2 // RUN: %clang_cc1 -verify=ref %s
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}}
13 constexpr int i = 2;
14 constexpr float f = 1.0f;
15 static_assert(f == 1.0f, "");
17 constexpr float f2 = 1u * f;
18 static_assert(f2 == 1.0f, "");
20 constexpr float f3 = 1.5;
21 constexpr int i3 = f3;
22 static_assert(i3 == 1, "");
24 constexpr bool b3 = f3;
25 static_assert(b3, "");
28 static_assert(1.0f + 3u == 4, "");
29 static_assert(4.0f / 1.0f == 4, "");
30 static_assert(10.0f * false == 0, "");
32 constexpr float floats[] = {1.0f, 2.0f, 3.0f, 4.0f};
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}}
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}}
42 /// Initialized by a double.
43 constexpr float df = 0.0;
44 /// The other way around.
45 constexpr double fd = 0.0f;
47 static_assert(0.0f == -0.0f, "");
49 const int k = 3 * (1.0f / 3.0f);
50 static_assert(k == 1, "");
52 constexpr bool b = 1.0;
53 static_assert(b, "");
55 constexpr double db = true;
56 static_assert(db == 1.0, "");
58 constexpr float fa[] = {1.0f, 2.0, 1, false};
59 constexpr double da[] = {1.0f, 2.0, 1, false};
61 constexpr float fm = __FLT_MAX__;
62 constexpr int someInt = fm; // ref-error {{must be initialized by a constant expression}} \
63 // ref-note {{is outside the range of representable values}} \
64 // expected-error {{must be initialized by a constant expression}} \
65 // expected-note {{is outside the range of representable values}}
67 namespace compound {
68 constexpr float f1() {
69 float f = 0;
70 f += 3.0;
71 f -= 3.0f;
73 f += 1;
74 f /= 1;
75 f /= 1.0;
76 f *= f;
78 f *= 2.0;
79 return f;
81 static_assert(f1() == 2, "");
83 constexpr float f2() {
84 float f = __FLT_MAX__;
85 f += 1.0;
86 return f;
88 static_assert(f2() == __FLT_MAX__, "");
90 constexpr float ff() {
91 float a[] = {1,2};
92 int i = 0;
94 // RHS should be evaluated before LHS, so this should
95 // write to a[1];
96 a[i++] += ++i;
97 #if __cplusplus <= 201402L
98 // expected-warning@-2 {{multiple unsequenced modifications}} \
99 // ref-warning@-2 {{multiple unsequenced modifications}}
100 #endif
102 return a[1];
104 static_assert(ff() == 3, "");
106 constexpr float intPlusDouble() {
107 int a = 0;
108 a += 2.0;
110 return a;
112 static_assert(intPlusDouble() == 2, "");
114 constexpr double doublePlusInt() {
115 double a = 0.0;
116 a += 2;
118 return a;
120 static_assert(doublePlusInt() == 2, "");
122 constexpr float boolPlusDouble() {
123 bool a = 0;
124 a += 1.0;
126 return a;
128 static_assert(boolPlusDouble(), "");
130 constexpr bool doublePlusbool() {
131 double a = 0.0;
132 a += true;
134 return a;
136 static_assert(doublePlusbool() == 1.0, "");
139 namespace unary {
140 constexpr float a() {
141 float f = 0.0;
142 assert(++f == 1.0);
143 assert(f == 1.0);
144 ++f;
145 f++;
146 assert(f == 3.0);
147 --f;
148 f--;
149 assert(f == 1.0);
150 return 1.0;
152 static_assert(a() == 1.0, "");
154 constexpr float b() {
155 float f = __FLT_MAX__;
156 f++;
157 return f;
159 static_assert(b() == __FLT_MAX__, "");
163 namespace ZeroInit {
164 template<typename FloatT>
165 struct A {
166 int a;
167 FloatT f;
170 constexpr A<float> a{12};
171 static_assert(a.f == 0.0f, "");
173 constexpr A<double> b{12};
174 static_assert(a.f == 0.0, "");
177 namespace LongDouble {
178 constexpr long double ld = 3.1425926539;
180 constexpr long double f() {
181 const long double L = __LDBL_MAX__;
183 return L;
185 static_assert(f() == __LDBL_MAX__, "");
187 #ifdef __FLOAT128__
188 constexpr __float128 f128() {
189 const __float128 L = __LDBL_MAX__;
191 return L;
193 static_assert(f128() == __LDBL_MAX__, "");
194 #endif
197 namespace Compare {
198 constexpr float nan = __builtin_nan("");
199 constexpr float inf = __builtin_inf();
200 static_assert(!(nan == nan), "");
201 static_assert(nan != nan, "");
202 static_assert(!(inf < nan), "");
203 static_assert(!(inf > nan), "");
206 namespace nan {
207 constexpr double nan = __builtin_nan("");
208 static_assert(nan);
210 constexpr double D1 = 1 + nan; // ref-error {{must be initialized by a constant expression}} \
211 // ref-note {{produces a NaN}} \
212 // expected-error {{must be initialized by a constant expression}} \
213 // expected-note {{produces a NaN}}
215 constexpr double D2 = __builtin_inf() / __builtin_inf(); // ref-error {{must be initialized by a constant expression}} \
216 // ref-note {{produces a NaN}} \
217 // expected-error {{must be initialized by a constant expression}} \
218 // expected-note {{produces a NaN}}