[PATCH] D122155: Add warning when eval-method is set in the presence of value unsafe floating-point calculations.

Zahira Ammarguellat via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 22 06:46:06 PDT 2022


zahiraam updated this revision to Diff 417279.
zahiraam marked 5 inline comments as done.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122155/new/

https://reviews.llvm.org/D122155

Files:
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/Sema/eval-method-with-unsafe-math.c


Index: clang/test/Sema/eval-method-with-unsafe-math.c
===================================================================
--- /dev/null
+++ clang/test/Sema/eval-method-with-unsafe-math.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -ffp-eval-method=source \
+// RUN: -verify %s
+
+// RUN: %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -fapprox-func -ffp-eval-method=source \
+// RUN: %s 2>&1 | FileCheck %s --check-prefix=WARN
+
+// RUN: %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math  -ffp-eval-method=source \
+// RUN: %s 2>&1 | FileCheck %s --check-prefix=WARN
+
+// RUN: %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -mreassociate -ffp-eval-method=source \
+// RUN: %s 2>&1 | FileCheck %s --check-prefix=WARN
+
+// expected-no-diagnostics
+
+float f1(float a, float b, float c) {
+  return a * b + c;
+  // WARN: setting the eval method via the '-ffp-eval-method' option or '#pragma clang fp eval_method' has not effect when numeric results of floating-point calculations aren't value-safe.
+}
+
+float f2(float a, float b, float c) {
+#pragma clang fp eval_method(double)
+  // WARN: setting the eval method via the '-ffp-eval-method' option or '#pragma clang fp eval_method' has not effect when numeric results of floating-point calculations aren't value-safe.
+  return a * b + c;
+}
Index: clang/lib/Sema/SemaAttr.cpp
===================================================================
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -486,6 +486,10 @@
     NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Extended);
     break;
   }
+  if (getLangOpts().ApproxFunc || getLangOpts().AllowFPReassoc ||
+      getLangOpts().AllowRecip)
+    Diags.Report(
+        diag::warn_eval_method_setting_is_meaningless_in_value_unsafe_context);
   FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
   CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
   PP.setCurrentFPEvalMethod(Loc, Value);
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -252,10 +252,22 @@
     // Use setting from TargetInfo.
     PP.setCurrentFPEvalMethod(SourceLocation(),
                               ctxt.getTargetInfo().getFPEvalMethod());
-  else
+  else {
     // Set initial value of __FLT_EVAL_METHOD__ from the command line.
     PP.setCurrentFPEvalMethod(SourceLocation(),
                               getLangOpts().getFPEvalMethod());
+    if (getLangOpts().ApproxFunc || getLangOpts().AllowFPReassoc ||
+        getLangOpts().AllowRecip)
+      // When these options are used, the compiler is allowed to make
+      // transformation that may affect the final result. For example
+      // (x+y)+z is transformed to x+(y+z) but may not give the same
+      // final result; it's not value safe.
+      // Another example can be to simlify x/x to 1.0 but x could be 0.0, INF
+      // or NaN. Final result may then differ.
+      Diags.Report(
+          diag::
+              warn_eval_method_setting_is_meaningless_in_value_unsafe_context);
+  }
   CurFPFeatures.setFPEvalMethod(PP.getCurrentFPEvalMethod());
 }
 
Index: clang/include/clang/Basic/DiagnosticCommonKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -124,6 +124,9 @@
   "'consteval' specifier is incompatible with C++ standards before C++20">,
   InGroup<CXX20Compat>, DefaultIgnore;
 
+def warn_eval_method_setting_is_meaningless_in_value_unsafe_context : Warning<
+  "setting the eval method via '-ffp-eval-method' or '#pragma clang fp eval_method' "
+  "has not effect when numeric results of floating-point calculations aren't value-safe.">, InGroup<Pragmas>;
 }
 
 let CategoryName = "Nullability Issue" in {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D122155.417279.patch
Type: text/x-patch
Size: 4056 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220322/ca3f5013/attachment.bin>


More information about the cfe-commits mailing list