[clang] f8b029c - [AST][NFC] Rename and refactor floating-point status checks in AST and ByteCode evaluators (#213750)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 7 07:03:09 PDT 2026
Author: lntue
Date: 2026-08-07T10:03:03-04:00
New Revision: f8b029ceb19ffa0f788ac390276019c885858152
URL: https://github.com/llvm/llvm-project/commit/f8b029ceb19ffa0f788ac390276019c885858152
DIFF: https://github.com/llvm/llvm-project/commit/f8b029ceb19ffa0f788ac390276019c885858152.diff
LOG: [AST][NFC] Rename and refactor floating-point status checks in AST and ByteCode evaluators (#213750)
To clarify the purpose of floating-point status checks in AST and
ByteCode evaluators during translation (as opposed to mandatory constant
expression evaluation):
- Rename checkFloatingPointResult to
checkFloatingPointResultForConstantFolding in ExprConstant.cpp
- Update its Doxygen documentation comment
- CheckFloatResult in Interp.cpp is essentially the same as (Result NaN
check + checkFloatingPointResultForConstantFolding). So we split the
part that is equivalent to checkFloatingPointResultForConstantFolding in
CheckFloatResult into a separate CheckFloatStatus function.
Added:
Modified:
clang/lib/AST/ByteCode/Interp.cpp
clang/lib/AST/ByteCode/Interp.h
clang/lib/AST/ExprConstant.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 5a5a12752dec5..f7e74811cc9f5 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1188,19 +1188,8 @@ bool CheckThis(InterpState &S, CodePtr OpPC) {
return false;
}
-bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
- APFloat::opStatus Status, FPOptions FPO) {
- // [expr.pre]p4:
- // If during the evaluation of an expression, the result is not
- // mathematically defined [...], the behavior is undefined.
- // FIXME: C++ rules require us to not conform to IEEE 754 here.
- if (Result.isNan()) {
- const SourceInfo &E = S.Current->getSource(OpPC);
- S.CCEDiag(E, diag::note_constexpr_float_arithmetic)
- << /*NaN=*/true << S.Current->getRange(OpPC);
- return S.noteUndefinedBehavior();
- }
-
+bool CheckFloatStatus(InterpState &S, CodePtr OpPC, APFloat::opStatus Status,
+ FPOptions FPO) {
// In a constant context, assume that any dynamic rounding mode or FP
// exception state matches the default floating-point environment.
if (S.inConstantContext())
@@ -1235,6 +1224,26 @@ bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
return true;
}
+bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
+ APFloat::opStatus Status, FPOptions FPO) {
+ // FIXME: The standard quote below is deleted by P3899R3.
+ // [expr.pre]p4:
+ // If during the evaluation of an expression, the result is not
+ // mathematically defined [...], the behavior is undefined.
+ // FIXME: C++ rules require us to not conform to IEEE 754 here.
+ // FIXME: The NaN check should not be applied outside of "constant contexts"
+ // because it prevents NaN propagation and the "invalid" status is the
+ // responsibility of CheckFloatStatus.
+ if (Result.isNan()) {
+ const SourceInfo &E = S.Current->getSource(OpPC);
+ S.CCEDiag(E, diag::note_constexpr_float_arithmetic)
+ << /*NaN=*/true << S.Current->getRange(OpPC);
+ return S.noteUndefinedBehavior();
+ }
+
+ return CheckFloatStatus(S, OpPC, Status, FPO);
+}
+
bool CheckDynamicMemoryAllocation(InterpState &S, CodePtr OpPC) {
if (S.getLangOpts().CPlusPlus20)
return true;
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 6c187f218a540..582cb108f5816 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -246,9 +246,26 @@ bool CheckDivRem(InterpState &S, CodePtr OpPC, const T &LHS, const T &RHS) {
/// Checks if the result of a floating-point operation is valid
/// in the current context.
+/// Notes:
+/// - CheckFloatStatus is the same as
+/// checkFloatingPointResultForConstantFolding in
+/// clang/lib/AST/ExprConstant.cpp.
+/// - CheckFloatResult will also check if the result is NaN, in addition to
+/// CheckFloatStatus's checks.
+// FIXME: P3899R3 (adopted by WG21 in June 2026) likely makes this interface
+// obsolete.
+// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3899r3.html
+// Also see the comment:
+// https://github.com/llvm/llvm-project/pull/213750/changes/2fea01449764e23b84ce6790bc7121d369546192#r3708712572
bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
APFloat::opStatus Status, FPOptions FPO);
+/// Check if the given floating-point evaluation status is allowed for
+/// compile-time constant folding during translation (as opposed to mandatory
+/// constant expression evaluation).
+bool CheckFloatStatus(InterpState &S, CodePtr OpPC, APFloat::opStatus Status,
+ FPOptions FPO);
+
/// Checks why the given DeclRefExpr is invalid.
bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR);
bool InvalidDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR,
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 38afb604a4e42..480d5119a5363 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2703,9 +2703,12 @@ static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E) {
return RM;
}
-/// Check if the given evaluation result is allowed for constant evaluation.
-static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E,
- APFloat::opStatus St) {
+/// Check if the given floating-point evaluation result is allowed for
+/// compile-time constant folding during translation (as opposed to mandatory
+/// constant expression evaluation).
+static bool checkFloatingPointResultForConstantFolding(EvalInfo &Info,
+ const Expr *E,
+ APFloat::opStatus St) {
// In a constant context, assume that any dynamic rounding mode or FP
// exception state matches the default floating-point environment.
if (Info.InConstantContext)
@@ -2757,7 +2760,7 @@ static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E,
APFloat Value = Result;
bool ignored;
St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
- return checkFloatingPointResult(Info, E, St);
+ return checkFloatingPointResultForConstantFolding(Info, E, St);
}
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E,
@@ -2780,7 +2783,7 @@ static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E,
Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
llvm::RoundingMode RM = getActiveRoundingMode(Info, E);
APFloat::opStatus St = Result.convertFromAPInt(Value, Value.isSigned(), RM);
- return checkFloatingPointResult(Info, E, St);
+ return checkFloatingPointResultForConstantFolding(Info, E, St);
}
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E,
@@ -2978,16 +2981,20 @@ static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E,
break;
}
+ // FIXME: The standard quote below is deleted by P3899R3.
// [expr.pre]p4:
// If during the evaluation of an expression, the result is not
// mathematically defined [...], the behavior is undefined.
// FIXME: C++ rules require us to not conform to IEEE 754 here.
+ // FIXME: The NaN check should not be applied outside of "constant contexts"
+ // because it prevents NaN propagation and the "invalid" status is the
+ // responsibility of checkFloatingPointResultForConstantFolding.
if (LHS.isNaN()) {
Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
return Info.noteUndefinedBehavior();
}
- return checkFloatingPointResult(Info, E, St);
+ return checkFloatingPointResultForConstantFolding(Info, E, St);
}
static bool handleLogicalOpForVector(const APInt &LHSValue,
@@ -5295,7 +5302,7 @@ struct IncDecSubobjectHandler {
St = Value.add(One, RM);
else
St = Value.subtract(One, RM);
- return checkFloatingPointResult(Info, E, St);
+ return checkFloatingPointResultForConstantFolding(Info, E, St);
}
bool foundPointer(APValue &Subobj, QualType SubobjType) {
if (!checkConst(SubobjType))
More information about the cfe-commits
mailing list