Skip to content

Commit a3d14fe

Browse files
spavloffllvmbot
authored andcommitted
[clang] Set FP options in Sema when instantiating CompoundStmt
When an expression is instantiated, TreeTransform skips ImplicitCastExpr nodes, assuming they are recreated when the instantiated expression is built. It breaks functions that use non-default floating-point options, because they are kept in these ImplicitCastExprs. In this case the recreated ImplicitCastExpr takes FP options from the current Sema state and not from AST node. To fix this issue the FP options in Sema object are set when a compound statement is cloned in TreeTransform. This change fixes llvm/llvm-project#64605 ([Regression 16 -> 17] Template instantiation ignores FENV_ACCESS being ON for both definition and instantiation). Differential Revision: https://reviews.llvm.org/D158158 (cherry picked from commit 0baf85c331090fbe2d2b42214ed0664d55feb0b5)
1 parent 1991da9 commit a3d14fe

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

clang/lib/Sema/TreeTransform.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7478,6 +7478,10 @@ StmtResult
74787478
TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
74797479
bool IsStmtExpr) {
74807480
Sema::CompoundScopeRAII CompoundScope(getSema());
7481+
Sema::FPFeaturesStateRAII FPSave(getSema());
7482+
if (S->hasStoredFPFeatures())
7483+
getSema().resetFPOptions(
7484+
S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
74817485

74827486
const Stmt *ExprResult = S->getStmtExprResult();
74837487
bool SubStmtInvalid = false;

clang/test/SemaCXX/template-64605.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 -ast-dump -ast-dump-filter=b_64605 %s | FileCheck %s
2+
3+
// https://github.com/llvm/llvm-project/issues/64605
4+
5+
#pragma STDC FENV_ACCESS ON
6+
template <typename>
7+
int b_64605() {
8+
int x;
9+
if ((float)0xFFFFFFFF != (float)0x100000000) {
10+
x = 1;
11+
}
12+
return x;
13+
}
14+
int f() { return b_64605<void>(); }
15+
16+
// CHECK: ImplicitCastExpr {{.*}} 'float' <IntegralToFloating> RoundingMath=1 AllowFEnvAccess=1
17+
// CHECK-NEXT: IntegerLiteral {{.*}} 4294967295
18+
19+
// CHECK: FunctionDecl {{.*}} b_64605 'int ()' implicit_instantiation
20+
// CHECK-NEXT: TemplateArgument type 'void'
21+
22+
// CHECK: ImplicitCastExpr {{.*}} 'float' <IntegralToFloating> RoundingMath=1 AllowFEnvAccess=1
23+
// CHECK-NEXT: IntegerLiteral {{.*}} 4294967295

0 commit comments

Comments
 (0)