[PATCH] D89360: Treat constant contexts as being in the default rounding mode.
Richard Smith - zygoloid via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 16 12:37:38 PDT 2020
rsmith updated this revision to Diff 298724.
rsmith added a comment.
- Add more testcases to demonstrate behavior in C.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D89360/new/
https://reviews.llvm.org/D89360
Files:
clang/lib/AST/ExprConstant.cpp
clang/test/Sema/rounding-math.c
clang/test/SemaCXX/rounding-math.cpp
Index: clang/test/SemaCXX/rounding-math.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/rounding-math.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-linux -verify=norounding %s
+// RUN: %clang_cc1 -triple x86_64-linux -verify=rounding %s -frounding-math
+// rounding-no-diagnostics
+
+#define fold(x) (__builtin_constant_p(x) ? (x) : (x))
+
+constexpr double a = 1.0 / 3.0;
+
+constexpr int f(int n) { return int(n * (1.0 / 3.0)); }
+
+using T = int[f(3)];
+using T = int[1];
+
+enum Enum { enum_a = f(3) };
+
+struct Bitfield {
+ unsigned int n : 1;
+ unsigned int m : f(3);
+};
+
+void f(Bitfield &b) {
+ b.n = int(6 * (1.0 / 3.0)); // norounding-warning {{changes value from 2 to 0}}
+}
+
+const int k = 3 * (1.0 / 3.0);
+static_assert(k == 1, "");
+
+void g() {
+ // FIXME: Constant-evaluating this initializer is surprising, and violates
+ // the recommended practice in C++ [expr.const]p12:
+ //
+ // Implementations should provide consistent results of floating-point
+ // evaluations, irrespective of whether the evaluation is performed during
+ // translation or during program execution.
+ const int k = 3 * (1.0 / 3.0);
+ static_assert(k == 1, "");
+}
+
+int *h() {
+ return new int[int(-3 * (1.0 / 3.0))]; // norounding-error {{too large}}
+}
Index: clang/test/Sema/rounding-math.c
===================================================================
--- /dev/null
+++ clang/test/Sema/rounding-math.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple x86_64-linux -verify=norounding %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c17 -verify=rounding-std %s -frounding-math
+// RUN: %clang_cc1 -triple x86_64-linux -std=gnu17 -verify=rounding-gnu %s -frounding-math
+
+#define fold(x) (__builtin_constant_p(x) ? (x) : (x))
+
+double a = 1.0 / 3.0;
+
+#define f(n) ((n) * (1.0 / 3.0))
+_Static_assert(fold((int)f(3)) == 1, "");
+
+typedef int T[fold((int)f(3))];
+typedef int T[1];
+
+enum Enum { enum_a = (int)f(3) };
+
+struct Bitfield {
+ unsigned int n : 1;
+ unsigned int m : fold((int)f(3));
+};
+
+void bitfield(struct Bitfield *b) {
+ b->n = (int)(6 * (1.0 / 3.0)); // norounding-warning {{changes value from 2 to 0}}
+}
+
+void vlas() {
+ // Under -frounding-math, this is a VLA.
+ // FIXME: Due to PR44406, in GNU mode we constant-fold the initializer resulting in a non-VLA.
+ typedef int vla[(int)(-3 * (1.0 / 3.0))]; // norounding-error {{negative size}} rounding-gnu-error {{negative size}}
+ struct X { vla v; }; // rounding-std-error {{fields must have a constant size}}
+}
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -2528,6 +2528,11 @@
/// Check if the given evaluation result is allowed for constant evaluation.
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E,
APFloat::opStatus St) {
+ // In a constant context, assume that any dynamic rounding mode or FP
+ // exception state matches the default floating-point environment.
+ if (Info.InConstantContext)
+ return true;
+
FPOptions FPO = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
if ((St & APFloat::opInexact) &&
FPO.getRoundingMode() == llvm::RoundingMode::Dynamic) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D89360.298724.patch
Type: text/x-patch
Size: 3362 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20201016/99d52daa/attachment-0001.bin>
More information about the cfe-commits
mailing list