llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: lntue <details> <summary>Changes</summary> 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. --- Full diff: https://github.com/llvm/llvm-project/pull/213750.diff 3 Files Affected: - (modified) clang/lib/AST/ByteCode/Interp.cpp (+18-13) - (modified) clang/lib/AST/ByteCode/Interp.h (+12) - (modified) clang/lib/AST/ExprConstant.cpp (+10-7) ``````````diff 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)) `````````` </details> https://github.com/llvm/llvm-project/pull/213750 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
