diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5087,6 +5087,10 @@ // 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 --- a/clang/test/CodeGen/fp-template.cpp +++ b/clang/test/CodeGen/fp-template.cpp @@ -45,10 +45,24 @@ // 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 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