Skip to content

Commit fde5924

Browse files
committed
[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 #63542. Differential Revision: https://reviews.llvm.org/D154359
1 parent 020cdaf commit fde5924

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5087,6 +5087,10 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
50875087
// PushDeclContext because we don't have a scope.
50885088
Sema::ContextRAII savedContext(*this, Function);
50895089

5090+
FPFeaturesStateRAII SavedFPFeatures(*this);
5091+
CurFPFeatures = FPOptions(getLangOpts());
5092+
FpPragmaStack.CurrentValue = FPOptionsOverride();
5093+
50905094
if (addInstantiatedParametersToScope(Function, PatternDecl, Scope,
50915095
TemplateArgs))
50925096
return;

clang/test/CodeGen/fp-template.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,24 @@ float func_03(float x, float y) {
4545
// CHECK: call float @llvm.experimental.constrained.fsub.f32({{.*}}, metadata !"round.upward", metadata !"fpexcept.ignore")
4646

4747

48-
// This pragma sets non-default rounding mode before delayed parsing occurs. It
49-
// is used to check that the parsing uses FP options defined by command line
50-
// options or by pragma before the template definition but not by this pragma.
51-
#pragma STDC FENV_ROUND FE_TOWARDZERO
48+
#pragma STDC FENV_ROUND FE_TONEAREST
49+
50+
namespace PR63542 {
51+
template <class Compare> float stable_sort(float x, Compare) {
52+
float result = x + x;
53+
stable_sort(x, int());
54+
return result;
55+
}
56+
float linkage_wrap() { return stable_sort(0.0, 1); }
57+
}
5258

59+
// CHECK-LABEL: define {{.*}} float @_ZN7PR6354211stable_sortIiEEffT_(
60+
// CHECK: fadd float
61+
62+
// These pragmas set non-default FP environment before delayed parsing occurs.
63+
// It is used to check that the parsing uses FP options defined by command line
64+
// options or by pragma before the template definition but not by these pragmas.
65+
#pragma STDC FENV_ROUND FE_TOWARDZERO
66+
#pragma STDC FENV_ACCESS ON
5367

5468
// CHECK: attributes #[[ATTR01]] = { {{.*}}strictfp

0 commit comments

Comments
 (0)