https://github.com/lntue created https://github.com/llvm/llvm-project/pull/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 checkFloatingPointResultForOpportunisticFolding in ExprConstant.cpp, update its Doxygen documentation comment, and refactor CheckFloatResult in Interp.cpp to delegate to CheckFloatStatus. >From 2fea01449764e23b84ce6790bc7121d369546192 Mon Sep 17 00:00:00 2001 From: Tue Ly <[email protected]> Date: Mon, 3 Aug 2026 19:28:23 +0000 Subject: [PATCH] [AST][ByteCode][NFC] Rename checkFloatingPointResult to checkFloatingPointResultForOpportunisticFolding 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 checkFloatingPointResultForOpportunisticFolding in ExprConstant.cpp, update its Doxygen documentation comment, and refactor CheckFloatResult in Interp.cpp to delegate to CheckFloatStatus. --- clang/lib/AST/ByteCode/Interp.cpp | 31 ++++++++++++++++++------------- clang/lib/AST/ByteCode/Interp.h | 12 ++++++++++++ clang/lib/AST/ExprConstant.cpp | 17 ++++++++++------- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 5a5a12752dec5..691cdf7436fe3 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,22 @@ 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) { + // [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(); + } + + 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..7235a6dd21120 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -246,9 +246,21 @@ 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 +/// checkFloatingPointResultForOpportunisticFolding in +/// clang/lib/AST/ExprConstant.cpp. +/// - CheckFloatResult will also check if the result is NaN, in addition to +/// CheckFloatStatus's checks. 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 +/// opportunistic 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 9d69de2a7c6fd..f84198e8bd766 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 +/// opportunistic compile-time constant folding during translation (as opposed +/// to mandatory constant expression evaluation). +static bool +checkFloatingPointResultForOpportunisticFolding(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 checkFloatingPointResultForOpportunisticFolding(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 checkFloatingPointResultForOpportunisticFolding(Info, E, St); } static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, @@ -2987,7 +2990,7 @@ static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, return Info.noteUndefinedBehavior(); } - return checkFloatingPointResult(Info, E, St); + return checkFloatingPointResultForOpportunisticFolding(Info, E, St); } static bool handleLogicalOpForVector(const APInt &LHSValue, @@ -5295,7 +5298,7 @@ struct IncDecSubobjectHandler { St = Value.add(One, RM); else St = Value.subtract(One, RM); - return checkFloatingPointResult(Info, E, St); + return checkFloatingPointResultForOpportunisticFolding(Info, E, St); } bool foundPointer(APValue &Subobj, QualType SubobjType) { if (!checkConst(SubobjType)) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
