https://github.com/JustinStitt updated 
https://github.com/llvm/llvm-project/pull/183826

>From dcabe20e2f7dd8216fe8678f0ea1f01d3ae51769 Mon Sep 17 00:00:00 2001
From: Justin Stitt <[email protected]>
Date: Fri, 27 Feb 2026 11:36:09 -0800
Subject: [PATCH 1/3] [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/include/clang/Basic/DiagnosticASTKinds.td      |  2 ++
 clang/lib/AST/ExprConstant.cpp                       | 11 +++++++++--
 clang/test/Sema/attr-overflow-behavior-constexpr.cpp |  2 +-
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td 
b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 1afae9b1fc1a2..36ebcc4cd1962 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -24,6 +24,8 @@ def note_constexpr_invalid_downcast : Note<
   "cannot cast object of dynamic type %0 to type %1">;
 def note_constexpr_overflow : Note<
   "value %0 is outside the range of representable values of type %1">;
+def note_constexpr_overflow_trap
+    : Note<"overflow on type %0 would trap at runtime">;
 def note_constexpr_negative_shift : Note<"negative shift count %0">;
 def note_constexpr_large_shift : Note<
   "shift count %0 >= width of type %1 (%2 bit%s2)">;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index feea97cd67534..e63423d6323ad 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2625,6 +2625,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) {
+  if (const auto *OBT = DestType->getAs<OverflowBehaviorType>();
+      OBT && OBT->isTrapKind()) {
+    Info.FFDiag(E, diag::note_constexpr_overflow_trap) << DestType;
+    return false;
+  }
   Info.CCEDiag(E, diag::note_constexpr_overflow)
     << SrcValue << DestType;
   return Info.noteUndefinedBehavior();
@@ -5143,14 +5148,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/test/Sema/attr-overflow-behavior-constexpr.cpp 
b/clang/test/Sema/attr-overflow-behavior-constexpr.cpp
index ea5bc7fdb9fbe..704f9b5a36b2c 100644
--- a/clang/test/Sema/attr-overflow-behavior-constexpr.cpp
+++ b/clang/test/Sema/attr-overflow-behavior-constexpr.cpp
@@ -11,7 +11,7 @@ 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 {{overflow on type 'no_trap_int' (aka 
'__ob_trap int') would trap at runtime}}
 }
 
 void constexpr_test() {

>From 586fd4a63c790b8b7c3bacb61e2815b3b54a1766 Mon Sep 17 00:00:00 2001
From: Justin Stitt <[email protected]>
Date: Mon, 2 Mar 2026 09:55:47 -0800
Subject: [PATCH 2/3] update diagnostic message

Signed-off-by: Justin Stitt <[email protected]>
---
 clang/include/clang/Basic/DiagnosticASTKinds.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td 
b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 36ebcc4cd1962..e506e0614933d 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -25,7 +25,7 @@ def note_constexpr_invalid_downcast : Note<
 def note_constexpr_overflow : Note<
   "value %0 is outside the range of representable values of type %1">;
 def note_constexpr_overflow_trap
-    : Note<"overflow on type %0 would trap at runtime">;
+    : Note<"constexpr evaluation failed as overflow on type %0 would trap">;
 def note_constexpr_negative_shift : Note<"negative shift count %0">;
 def note_constexpr_large_shift : Note<
   "shift count %0 >= width of type %1 (%2 bit%s2)">;

>From ed76cf5e3096ada058cf9b9248b73429a7168d27 Mon Sep 17 00:00:00 2001
From: Justin Stitt <[email protected]>
Date: Mon, 2 Mar 2026 10:00:53 -0800
Subject: [PATCH 3/3] add new tests

Signed-off-by: Justin Stitt <[email protected]>
---
 .../Sema/attr-overflow-behavior-constexpr.cpp     | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/clang/test/Sema/attr-overflow-behavior-constexpr.cpp 
b/clang/test/Sema/attr-overflow-behavior-constexpr.cpp
index 704f9b5a36b2c..671d9a8bf1dcc 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 {{overflow on type 'no_trap_int' (aka 
'__ob_trap int') would trap at runtime}}
+  return a - b; // expected-note {{constexpr evaluation failed as overflow on 
type 'no_trap_int' (aka '__ob_trap int') would trap}}
+}
+
+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

Reply via email to