1 // RUN: %clang_cc1 -triple x86_64-linux -verify=norounding -Wno-unknown-pragmas %s
2 // RUN: %clang_cc1 -triple x86_64-linux -verify=rounding %s -frounding-math -Wno-unknown-pragmas
3 // RUN: %clang_cc1 -triple x86_64-linux -verify=rounding %s -frounding-math -fexperimental-new-constant-interpreter -Wno-unknown-pragmas
4 // rounding-no-diagnostics
6 #define fold(x) (__builtin_constant_p(x) ? (x) : (x))
8 constexpr double a
= 1.0 / 3.0;
10 constexpr int f(int n
) { return int(n
* (1.0 / 3.0)); }
15 enum Enum
{ enum_a
= f(3) };
19 unsigned int m
: f(3);
23 b
.n
= int(6 * (1.0 / 3.0)); // norounding-warning {{changes value from 2 to 0}}
26 const int k
= 3 * (1.0 / 3.0);
27 static_assert(k
== 1, "");
30 // FIXME: Constant-evaluating this initializer is surprising, and violates
31 // the recommended practice in C++ [expr.const]p12:
33 // Implementations should provide consistent results of floating-point
34 // evaluations, irrespective of whether the evaluation is performed during
35 // translation or during program execution.
36 const int k
= 3 * (1.0 / 3.0);
37 static_assert(k
== 1, "");
41 return new int[int(-3 * (1.0 / 3.0))]; // norounding-error {{too large}}
45 // nextUp(1.F) == 0x1.000002p0F
46 static_assert(1.0F
+ 0x0.000001p0F
== 0x1.0p0F
, "");
48 char Arr01
[1 + (1.0F
+ 0x0.000001p0F
> 1.0F
)];
49 static_assert(sizeof(Arr01
) == 1, "");
52 int : (1.0F
+ 0x0.000001p0F
> 1.0F
);
55 static_assert(sizeof(S1
) == sizeof(int), "");
57 #pragma STDC FENV_ROUND FE_UPWARD
58 static_assert(1.0F
+ 0x0.000001p0F
== 0x1.000002p0F
, "");
60 char Arr01u
[1 + (1.0F
+ 0x0.000001p0F
> 1.0F
)];
61 static_assert(sizeof(Arr01u
) == 2, "");
64 int : (1.0F
+ 0x0.000001p0F
> 1.0F
);
67 static_assert(sizeof(S1u
) > sizeof(int), "");
69 #pragma STDC FENV_ROUND FE_DOWNWARD
70 static_assert(1.0F
+ 0x0.000001p0F
== 1.0F
, "");
72 char Arr01d
[1 + (1.0F
+ 0x0.000001p0F
> 1.0F
)];
73 static_assert(sizeof(Arr01d
) == 1, "");
76 int : (1.0F
+ 0x0.000001p0F
> 1.0F
);
79 static_assert(sizeof(S1d
) == sizeof(int), "");
81 constexpr float incr_down(float k
) {
87 // 0x1.0p23 = 8388608.0, inc(8388608.0) = 8388609.0
88 static_assert(incr_down(0x1.0p23F
) == 0x1.000002p23F
, "");
89 // 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round down -> 16777216.0
90 static_assert(incr_down(0x1.0p24F
) == 0x1.0p24F
, "");
92 #pragma STDC FENV_ROUND FE_UPWARD
93 constexpr float incr_up(float k
) {
98 static_assert(incr_up(0x1.0p23F
) == 0x1.000002p23F
, "");
99 // 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round up -> 16777218.0
100 static_assert(incr_up(0x1.0p24F
) == 0x1.000002p24F
, "");