[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