zahiraam created this revision.
zahiraam added reviewers: andrew.w.kaylor, aaron.ballman, rjmccall, thakis, 
fhahn.
Herald added a project: All.
zahiraam requested review of this revision.
Herald added a project: clang.

Setting the eval method via the `ffp-eval-method` option or via the `#pragma 
clang fp eval_method` when numeric results of floating-point calculations 
aren't value safe, is meaningless.
This patch adds code to warn the user of this.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122155

Files:
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/lib/Parse/ParseStmt.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,42 @@
+// 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: -verify %s -DWARN
+
+// RUN: %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math  -ffp-eval-method=source \
+// RUN: -verify %s -DWARN
+
+// RUN: %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -mreassociate -ffp-eval-method=source \
+// RUN: -verify %s -DWARN
+
+#ifndef WARN
+// expected-no-diagnostics
+float f1(float a, float b, float c) {
+  return a * b + c;
+}
+
+float f2(float a, float b, float c) {
+#pragma clang fp eval_method(double)
+  return a * b + c;
+}
+
+#endif
+
+#ifdef WARN
+float f3(float a, float b, float c) {
+  // expected-warning@+1{{setting the eval method via the `ffp-eval-method` 
option or the `pragma clang fp eval_method` is meaningless when numeric results 
of floating-point calculations aren't value-safe.}}
+  return a * b + c;
+}
+
+float f4(float a, float b, float c) {
+  // expected-warning@+1{{setting the eval method via the `ffp-eval-method` 
option or the `pragma clang fp eval_method` is meaningless when numeric results 
of floating-point calculations aren't value-safe.}}
+#pragma clang fp eval_method(double)
+  // expected-warning@+1{{setting the eval method via the `ffp-eval-method` 
option or the `pragma clang fp eval_method` is meaningless when numeric results 
of floating-point calculations aren't value-safe.}}
+  return a * b + c;
+}
+#endif
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)
+    Diag(Loc,
+         
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/Parse/ParseStmt.cpp
===================================================================
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1062,6 +1062,13 @@
 
   StmtVector Stmts;
 
+  if (Tok.isNot(tok::annot_pragma_fp) &&
+      getLangOpts().getFPEvalMethod() != LangOptions::FEM_UnsetOnCommandLine &&
+      (getLangOpts().ApproxFunc || getLangOpts().AllowFPReassoc ||
+       getLangOpts().AllowRecip))
+    Diag(Tok.getLocation(),
+         
diag::warn_eval_method_setting_is_meaningless_in_value_unsafe_context);
+
   // "__label__ X, Y, Z;" is the GNU "Local Label" extension.  These are
   // only allowed at the start of a compound stmt regardless of the language.
   while (Tok.is(tok::kw___label__)) {
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 the `ffp-eval-method` option or the `pragma 
clang fp eval_method`"
+  " is meaningless when numeric results of floating-point calculations aren't 
value-safe.">, InGroup<Pragmas>;
 }
 
 let CategoryName = "Nullability Issue" in {


Index: clang/test/Sema/eval-method-with-unsafe-math.c
===================================================================
--- /dev/null
+++ clang/test/Sema/eval-method-with-unsafe-math.c
@@ -0,0 +1,42 @@
+// 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: -verify %s -DWARN
+
+// RUN: %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math  -ffp-eval-method=source \
+// RUN: -verify %s -DWARN
+
+// RUN: %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -mreassociate -ffp-eval-method=source \
+// RUN: -verify %s -DWARN
+
+#ifndef WARN
+// expected-no-diagnostics
+float f1(float a, float b, float c) {
+  return a * b + c;
+}
+
+float f2(float a, float b, float c) {
+#pragma clang fp eval_method(double)
+  return a * b + c;
+}
+
+#endif
+
+#ifdef WARN
+float f3(float a, float b, float c) {
+  // expected-warning@+1{{setting the eval method via the `ffp-eval-method` option or the `pragma clang fp eval_method` is meaningless when numeric results of floating-point calculations aren't value-safe.}}
+  return a * b + c;
+}
+
+float f4(float a, float b, float c) {
+  // expected-warning@+1{{setting the eval method via the `ffp-eval-method` option or the `pragma clang fp eval_method` is meaningless when numeric results of floating-point calculations aren't value-safe.}}
+#pragma clang fp eval_method(double)
+  // expected-warning@+1{{setting the eval method via the `ffp-eval-method` option or the `pragma clang fp eval_method` is meaningless when numeric results of floating-point calculations aren't value-safe.}}
+  return a * b + c;
+}
+#endif
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)
+    Diag(Loc,
+         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/Parse/ParseStmt.cpp
===================================================================
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1062,6 +1062,13 @@
 
   StmtVector Stmts;
 
+  if (Tok.isNot(tok::annot_pragma_fp) &&
+      getLangOpts().getFPEvalMethod() != LangOptions::FEM_UnsetOnCommandLine &&
+      (getLangOpts().ApproxFunc || getLangOpts().AllowFPReassoc ||
+       getLangOpts().AllowRecip))
+    Diag(Tok.getLocation(),
+         diag::warn_eval_method_setting_is_meaningless_in_value_unsafe_context);
+
   // "__label__ X, Y, Z;" is the GNU "Local Label" extension.  These are
   // only allowed at the start of a compound stmt regardless of the language.
   while (Tok.is(tok::kw___label__)) {
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 the `ffp-eval-method` option or the `pragma clang fp eval_method`"
+  " is meaningless when numeric results of floating-point calculations aren't value-safe.">, InGroup<Pragmas>;
 }
 
 let CategoryName = "Nullability Issue" in {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to