https://github.com/JustinStitt updated https://github.com/llvm/llvm-project/pull/183826
>From 360e49704eab8f1e70af62a744182ea91c59ee7e Mon Sep 17 00:00:00 2001 From: Justin Stitt <[email protected]> Date: Fri, 27 Feb 2026 11:36:09 -0800 Subject: [PATCH] [Clang] Fix constexpr inc/Dec operators for OverflowBehaviorTypes __ob_wrap types were not being handled properly by constexpr pre/post-inc/dec operations causing static_asserts() to fail unexpectedly. Fix those by checking if we're dealing with an OBT wrap type specifically. Also add a diagnostic to help inform users as to why __ob_trap can't be an Integer Constant Expression when a compile-time overflow is detected. Fixes: #183760Signed-off-by: Justin Stitt <[email protected]> --- clang/lib/AST/ExprConstant.cpp | 13 +++++++++---- clang/lib/Sema/SemaOverload.cpp | 2 ++ .../Sema/attr-overflow-behavior-constexpr.cpp | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f233ff76632ae..43409fd2af82e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2627,8 +2627,11 @@ static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, template<typename T> static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType) { - Info.CCEDiag(E, diag::note_constexpr_overflow) - << SrcValue << DestType; + Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType; + if (const auto *OBT = DestType->getAs<OverflowBehaviorType>(); + OBT && OBT->isTrapKind()) { + return false; + } return Info.noteUndefinedBehavior(); } @@ -5172,14 +5175,16 @@ struct IncDecSubobjectHandler { if (AccessKind == AK_Increment) { ++Value; - if (!WasNegative && Value.isNegative() && E->canOverflow()) { + if (!WasNegative && Value.isNegative() && E->canOverflow() && + !SubobjType.isWrapType()) { APSInt ActualValue(Value, /*IsUnsigned*/true); return HandleOverflow(Info, E, ActualValue, SubobjType); } } else { --Value; - if (WasNegative && !Value.isNegative() && E->canOverflow()) { + if (WasNegative && !Value.isNegative() && E->canOverflow() && + !SubobjType.isWrapType()) { unsigned BitWidth = Value.getBitWidth(); APSInt ActualValue(Value.sext(BitWidth + 1), /*IsUnsigned*/false); ActualValue.setBit(BitWidth); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index e5c4c59e9ffbb..6cada8eff0107 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -2942,6 +2942,8 @@ bool Sema::IsOverflowBehaviorTypeConversion(QualType FromType, return false; if (FromType->isOverflowBehaviorType() && !ToType->isOverflowBehaviorType()) { + if (ToType->isBooleanType()) + return false; // Don't allow implicit conversion from OverflowBehaviorType to scoped enum if (const EnumType *ToEnumType = ToType->getAs<EnumType>()) { const EnumDecl *ToED = ToEnumType->getDecl()->getDefinitionOrSelf(); diff --git a/clang/test/Sema/attr-overflow-behavior-constexpr.cpp b/clang/test/Sema/attr-overflow-behavior-constexpr.cpp index ea5bc7fdb9fbe..1d81d3a243c1e 100644 --- a/clang/test/Sema/attr-overflow-behavior-constexpr.cpp +++ b/clang/test/Sema/attr-overflow-behavior-constexpr.cpp @@ -11,7 +11,17 @@ constexpr wrap_int add(wrap_int a, wrap_int b) { } constexpr no_trap_int sub(no_trap_int a, no_trap_int b) { - return a - b; // expected-note {{-2147483649 is outside the range of representable values}} + return a - b; // expected-note {{value -2147483649 is outside the range of representable values of type 'no_trap_int' (aka '__ob_trap int')}} +} + +constexpr wrap_int preinc(wrap_int a) { + ++a; + return a; +} + +constexpr wrap_int postinc(wrap_int a) { + a++; + return a; } void constexpr_test() { @@ -22,6 +32,9 @@ void constexpr_test() { constexpr no_trap_int min = -2147483648; constexpr no_trap_int one_nw = 1; constexpr no_trap_int res = sub(min, one_nw); // expected-error {{constexpr variable 'res' must be initialized by a constant expression}} expected-note {{in call to 'sub(-2147483648, 1)'}} + + static_assert(preinc(max) == -2147483648, "preinc wrapping failed"); + static_assert(postinc(max) == -2147483648, "postinc wrapping failed"); } template <typename T> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
