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)) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
