[PATCH] D79631: #pragma float_control should be permitted at namespace scope

Melanie Blower via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri May 8 08:33:08 PDT 2020


mibintc created this revision.
mibintc added reviewers: rjmccall, erichkeane.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

I got a  bug report from Intel that https://reviews.llvm.org/D72841 was causing a crash on Windows in vs2017 <numeric> header in /std:c++17 mode, because #pragma float_control is used in a namespace. This patch allows float_control to be in a namespace. I checked the Microsoft compiler to see if the namespace caused the effectiveness of the pragma to be scoped (i.e. a pragma in the namespace would not be effective after the namespace closed) and the pragma is still effective after the namespace. I added the test case that I used for the investigation to the LIT tests. I used this compile line and checked the assembly. cl -c test.cpp -Fatest.asm /arch:AVX2 -O2 ; when the pragma is in effect the div instruction is not eliminated.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79631

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaAttr.cpp
  clang/test/CodeGen/fp-floatcontrol-pragma.cpp
  clang/test/Parser/fp-floatcontrol-syntax.cpp


Index: clang/test/Parser/fp-floatcontrol-syntax.cpp
===================================================================
--- clang/test/Parser/fp-floatcontrol-syntax.cpp
+++ clang/test/Parser/fp-floatcontrol-syntax.cpp
@@ -10,10 +10,10 @@
 #pragma float_control(pop)
 #pragma float_control(precise, on, push)
 void check_stack() {
-#pragma float_control(push)                   // expected-error {{can only appear at file scope}}
-#pragma float_control(pop)                    // expected-error {{can only appear at file scope}}
-#pragma float_control(precise, on, push)      // expected-error {{can only appear at file scope}}
-#pragma float_control(except, on, push)       // expected-error {{can only appear at file scope}}
+#pragma float_control(push)                   // expected-error {{can only appear at file scope or namespace scope}}
+#pragma float_control(pop)                    // expected-error {{can only appear at file scope or namespace scope}}
+#pragma float_control(precise, on, push)      // expected-error {{can only appear at file scope or namespace scope}}
+#pragma float_control(except, on, push)       // expected-error {{can only appear at file scope or namespace scope}}
 #pragma float_control(except, on, push, junk) // expected-error {{float_control is malformed}}
   return;
 }
Index: clang/test/CodeGen/fp-floatcontrol-pragma.cpp
===================================================================
--- clang/test/CodeGen/fp-floatcontrol-pragma.cpp
+++ clang/test/CodeGen/fp-floatcontrol-pragma.cpp
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -DEXCEPT=1 -fcxx-exceptions -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NS %s
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
 // RUN: %clang_cc1 -verify -DFENV_ON=1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
@@ -59,3 +60,38 @@
   z = z * z;
 //CHECK: = fmul float
 }
+
+#if EXCEPT
+namespace ns {
+// Check that pragma float_control can appear in namespace.
+#pragma float_control(except, on, push)
+float exc_on(double x, float zero) {
+// CHECK-NS: define {{.*}}exc_on{{.*}}
+  {} try {
+    x = 1.0 / zero; /* division by zero, the result unused */
+//CHECK-NS: llvm.experimental.constrained.fdiv{{.*}}
+  } catch (...) {}
+  return zero;
+}
+}
+
+// Check pragma is still effective after namespace closes
+float exc_still_on(double x, float zero) {
+// CHECK-NS: define {{.*}}exc_still_on{{.*}}
+  {} try {
+    x = 1.0 / zero; /* division by zero, the result unused */
+//CHECK-NS: llvm.experimental.constrained.fdiv{{.*}}
+  } catch (...) {}
+  return zero;
+}
+
+#pragma float_control(pop)
+float exc_off(double x, float zero) {
+// CHECK-NS: define {{.*}}exc_off{{.*}}
+  {} try {
+    x = 1.0 / zero; /* division by zero, the result unused */
+//CHECK-NS: fdiv contract double
+  } catch (...) {}
+  return zero;
+}
+#endif // EXCEPT
Index: clang/lib/Sema/SemaAttr.cpp
===================================================================
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -413,8 +413,8 @@
   auto NewValue = FpPragmaStack.CurrentValue;
   FPOptions NewFPFeatures(NewValue);
   if ((Action == PSK_Push_Set || Action == PSK_Push || Action == PSK_Pop) &&
-      !CurContext->isTranslationUnit()) {
-    // Push and pop can only occur at file scope.
+      !(CurContext->isTranslationUnit()) && !CurContext->isNamespace()) {
+    // Push and pop can only occur at file or namespace scope.
     Diag(Loc, diag::err_pragma_fc_pp_scope);
     return;
   }
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -860,7 +860,7 @@
 def warn_pragma_pop_failed : Warning<"#pragma %0(pop, ...) failed: %1">,
   InGroup<IgnoredPragmas>;
 def err_pragma_fc_pp_scope : Error<
-  "'#pragma float_control push/pop' can only appear at file scope">;
+  "'#pragma float_control push/pop' can only appear at file scope or namespace scope">;
 def err_pragma_fc_noprecise_requires_nofenv : Error<
   "'#pragma float_control(precise, off)' is illegal when fenv_access is enabled">;
 def err_pragma_fc_except_requires_precise : Error<


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79631.262879.patch
Type: text/x-patch
Size: 4275 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200508/dbf99a26/attachment-0001.bin>


More information about the cfe-commits mailing list