Author: Serge Pavlov
Date: 2023-07-13T11:49:00+07:00
New Revision: fde5924dcc69fe814085482df259b8cfee236f2c

URL: 
https://github.com/llvm/llvm-project/commit/fde5924dcc69fe814085482df259b8cfee236f2c
DIFF: 
https://github.com/llvm/llvm-project/commit/fde5924dcc69fe814085482df259b8cfee236f2c.diff

LOG: [clang] Reset FP options before template instantiation

AST nodes that may depend on FP options keep them as a difference
relative to the options outside the AST node. At the moment of
instantiation the FP options may be different from the default values,
defined by command-line option. In such case FP attributes would have
unexpected values. For example, the code:

    template <class C> void func_01(int last, C) {
      func_01(last, int());
    }
    void func_02() { func_01(0, 1); }
    #pragma STDC FENV_ACCESS ON

caused compiler crash, because template instantiation takes place at the
end of translation unit, where pragma STDC FENV_ACCESS is in effect. As
a result, code in the template instantiation would use constrained
intrinsics while the function does not have StrictFP attribute.

To solve this problem, FP attributes in Sema must be set to default
values, defined by command line options.

This change resolves https://github.com/llvm/llvm-project/issues/63542.

Differential Revision: https://reviews.llvm.org/D154359

Added: 
    

Modified: 
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/test/CodeGen/fp-template.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 492fe8ba1b143c..9e5f85b0f9166b 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5087,6 +5087,10 @@ void Sema::InstantiateFunctionDefinition(SourceLocation 
PointOfInstantiation,
     // PushDeclContext because we don't have a scope.
     Sema::ContextRAII savedContext(*this, Function);
 
+    FPFeaturesStateRAII SavedFPFeatures(*this);
+    CurFPFeatures = FPOptions(getLangOpts());
+    FpPragmaStack.CurrentValue = FPOptionsOverride();
+
     if (addInstantiatedParametersToScope(Function, PatternDecl, Scope,
                                          TemplateArgs))
       return;

diff  --git a/clang/test/CodeGen/fp-template.cpp 
b/clang/test/CodeGen/fp-template.cpp
index e0ea8e4d12ad34..a945b23fff1095 100644
--- a/clang/test/CodeGen/fp-template.cpp
+++ b/clang/test/CodeGen/fp-template.cpp
@@ -45,10 +45,24 @@ float func_03(float x, float y) {
 // CHECK:       call float @llvm.experimental.constrained.fsub.f32({{.*}}, 
metadata !"round.upward", metadata !"fpexcept.ignore")
 
 
-// This pragma sets non-default rounding mode before delayed parsing occurs. It
-// is used to check that the parsing uses FP options defined by command line
-// options or by pragma before the template definition but not by this pragma.
-#pragma STDC FENV_ROUND FE_TOWARDZERO
+#pragma STDC FENV_ROUND FE_TONEAREST
+
+namespace PR63542 {
+  template <class Compare> float stable_sort(float x, Compare) {
+    float result = x + x;
+    stable_sort(x, int());
+    return result;
+  }
+  float linkage_wrap() { return stable_sort(0.0, 1); }
+}
 
+// CHECK-LABEL: define {{.*}} float @_ZN7PR6354211stable_sortIiEEffT_(
+// CHECK:         fadd float
+
+// These pragmas set non-default FP environment before delayed parsing occurs.
+// It is used to check that the parsing uses FP options defined by command line
+// options or by pragma before the template definition but not by these 
pragmas.
+#pragma STDC FENV_ROUND FE_TOWARDZERO
+#pragma STDC FENV_ACCESS ON
 
 // CHECK: attributes #[[ATTR01]] = { {{.*}}strictfp


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to