https://github.com/akash-manna-sky updated 
https://github.com/llvm/llvm-project/pull/221134

>From f729b942548041020759635b87462afd3c6e9a1b Mon Sep 17 00:00:00 2001
From: Akash Manna <[email protected]>
Date: Fri, 4 Sep 2026 10:41:21 +0530
Subject: [PATCH 1/3] [Clang] Diagnose fixed point arithmetic with _BitInt and
 overflow behavior types

GetFixedPointRank assumes both operands are BuiltinTypes, but the
fixed point branch of UsualArithmeticConversions let any arithmetic
type through. _BitInt was special-cased in #199912, yet overflow
behavior types hit the same assertion.

Check for BuiltinType at the fixed point branch itself, so every
non-builtin operand is rejected with the usual invalid-operands
diagnostic, and make the conditional operator diagnose any failed
conversion instead of only the _BitInt case.

Fixes #191701
---
 clang/docs/ReleaseNotes.md  |  1 +
 clang/lib/Sema/SemaExpr.cpp | 18 +++++++++---------
 clang/test/Sema/GH191701.c  | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 42 insertions(+), 9 deletions(-)
 create mode 100644 clang/test/Sema/GH191701.c

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 042d7112dbe7d..69566f10bb597 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -494,6 +494,7 @@ features cannot lower the translation-unit ABI level;
 - Fixed a crash when declaring a member template within a local class inside 
an OpenMP region. (#GH216052)
 - Fixed a bug where repeated #imports of modular headers in non-modular 
compilation were translated to #pragma clang module import. (#GH216924)
 - Fixed an assertion when `#pragma omp declare simd` or `#pragma omp declare 
variant` is followed by another OpenMP declarative directive containing a 
qualified identifier. (#GH217204)
+- Fixed an assertion failure when a fixed point type was used in arithmetic 
with a `_BitInt` or overflow behavior type; the combination is now diagnosed as 
invalid operands. (#GH191701)
 
 #### Bug Fixes to Compiler Builtins
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c93efeb928c56..e0d2298617a7c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1757,10 +1757,6 @@ QualType Sema::UsualArithmeticConversions(ExprResult 
&LHS, ExprResult &RHS,
 
   // At this point, we have two different arithmetic types.
 
-  if ((LHSType->isFixedPointType() && RHSType->isBitIntType()) ||
-      (LHSType->isBitIntType() && RHSType->isFixedPointType()))
-    return QualType();
-
   // Diagnose attempts to convert between __ibm128, __float128 and long double
   // where such conversions currently can't be handled.
   if (unsupportedTypeConversion(*this, LHSType, RHSType))
@@ -1781,8 +1777,13 @@ QualType Sema::UsualArithmeticConversions(ExprResult 
&LHS, ExprResult &RHS,
     return handleComplexIntConversion(*this, LHS, RHS, LHSType, RHSType,
                                       ACK == ArithConvKind::CompAssign);
 
-  if (LHSType->isFixedPointType() || RHSType->isFixedPointType())
+  if (LHSType->isFixedPointType() || RHSType->isFixedPointType()) {
+    // N1169 4.1.4 only defines conversions between fixed point types and the
+    // standard integer types, so reject e.g. _BitInt or overflow behavior 
types.
+    if (!LHSType->getAs<BuiltinType>() || !RHSType->getAs<BuiltinType>())
+      return QualType();
     return handleFixedPointConversion(*this, LHSType, RHSType);
+  }
 
   if (LHSType->isOverflowBehaviorType() || RHSType->isOverflowBehaviorType())
     return handleOverflowBehaviorTypeConversion(
@@ -8983,10 +8984,9 @@ QualType Sema::CheckConditionalOperands(ExprResult 
&Cond, ExprResult &LHS,
   // If both operands have arithmetic type, do the usual arithmetic conversions
   // to find a common type: C99 6.5.15p3,5.
   if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) {
-    // Disallow invalid arithmetic conversions, such as those between bit-
-    // precise integers types of different sizes, or between a bit-precise
-    // integer and another type.
-    if (ResTy.isNull() && (LHSTy->isBitIntType() || RHSTy->isBitIntType())) {
+    // Disallow invalid arithmetic conversions, such as those between a
+    // bit-precise integer and a fixed point type.
+    if (ResTy.isNull()) {
       Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
           << LHSTy << RHSTy << LHS.get()->getSourceRange()
           << RHS.get()->getSourceRange();
diff --git a/clang/test/Sema/GH191701.c b/clang/test/Sema/GH191701.c
new file mode 100644
index 0000000000000..446f2bc3bad40
--- /dev/null
+++ b/clang/test/Sema/GH191701.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -ffixed-point 
-fexperimental-overflow-behavior-types %s
+
+// Fixed point types have no conversions with _BitInt or overflow behavior 
types.
+
+#define test(e, t) _Generic (e, default : 0, t : 1)
+
+void GH191701(_Fract ci) {
+  _BitInt(31) bi = 0;
+  _Static_assert(test(ci + bi, _Complex int), ""); // expected-error {{invalid 
operands to binary expression ('_Fract' and '_BitInt(31)')}}
+}
+
+void bitint(int c, _Fract f, _Accum a, _Sat short _Fract sf, _BitInt(31) bi,
+            unsigned _BitInt(8) ubi) {
+  (void)(f + bi);   // expected-error {{invalid operands to binary expression 
('_Fract' and '_BitInt(31)')}}
+  (void)(bi + f);   // expected-error {{invalid operands to binary expression 
('_BitInt(31)' and '_Fract')}}
+  (void)(a - bi);   // expected-error {{invalid operands to binary expression 
('_Accum' and '_BitInt(31)')}}
+  (void)(bi * a);   // expected-error {{invalid operands to binary expression 
('_BitInt(31)' and '_Accum')}}
+  (void)(sf / ubi); // expected-error {{invalid operands to binary expression 
('_Sat short _Fract' and 'unsigned _BitInt(8)')}}
+  (void)(f < bi);   // expected-error {{invalid operands to binary expression 
('_Fract' and '_BitInt(31)')}}
+  (void)(ubi == a); // expected-error {{invalid operands to binary expression 
('unsigned _BitInt(8)' and '_Accum')}}
+  f += bi;          // expected-error {{invalid operands to binary expression 
('_Fract' and '_BitInt(31)')}}
+  bi -= a;          // expected-error {{invalid operands to binary expression 
('_BitInt(31)' and '_Accum')}}
+  (void)(c ? f : bi); // expected-error {{incompatible operand types ('_Fract' 
and '_BitInt(31)')}}
+}
+
+void overflow_behavior(int c, _Fract f, _Accum a, int __ob_wrap w,
+                       long __ob_trap t) {
+  (void)(f + w);   // expected-error {{invalid operands to binary expression 
('_Fract' and '__ob_wrap int')}}
+  (void)(t * a);   // expected-error {{invalid operands to binary expression 
('__ob_trap long' and '_Accum')}}
+  a -= w;          // expected-error {{invalid operands to binary expression 
('_Accum' and '__ob_wrap int')}}
+  (void)(c ? w : f); // expected-error {{incompatible operand types 
('__ob_wrap int' and '_Fract')}}
+}

>From ebe787faf87633e741952574e8e41f9518c0f244 Mon Sep 17 00:00:00 2001
From: Akash Manna <[email protected]>
Date: Fri, 4 Sep 2026 10:54:42 +0530
Subject: [PATCH 2/3] Fix the formatting issue

---
 clang/lib/Sema/SemaExpr.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index e0d2298617a7c..97eec9dc5b867 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1779,7 +1779,8 @@ QualType Sema::UsualArithmeticConversions(ExprResult 
&LHS, ExprResult &RHS,
 
   if (LHSType->isFixedPointType() || RHSType->isFixedPointType()) {
     // N1169 4.1.4 only defines conversions between fixed point types and the
-    // standard integer types, so reject e.g. _BitInt or overflow behavior 
types.
+    // standard integer types, so reject e.g. _BitInt or overflow behavior
+    // types.
     if (!LHSType->getAs<BuiltinType>() || !RHSType->getAs<BuiltinType>())
       return QualType();
     return handleFixedPointConversion(*this, LHSType, RHSType);

>From de1518de6b7b917a352730478a22f67c86346721 Mon Sep 17 00:00:00 2001
From: Akash Manna <[email protected]>
Date: Sat, 5 Sep 2026 00:35:23 +0530
Subject: [PATCH 3/3] Cite ISO/IEC TR 18037 instead of N1169 in the fixed point
 comment

---
 clang/lib/Sema/SemaExpr.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 97eec9dc5b867..8f2de66d3c883 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1778,9 +1778,9 @@ QualType Sema::UsualArithmeticConversions(ExprResult 
&LHS, ExprResult &RHS,
                                       ACK == ArithConvKind::CompAssign);
 
   if (LHSType->isFixedPointType() || RHSType->isFixedPointType()) {
-    // N1169 4.1.4 only defines conversions between fixed point types and the
-    // standard integer types, so reject e.g. _BitInt or overflow behavior
-    // types.
+    // ISO/IEC TR 18037 4.1.4 only defines conversions between fixed point
+    // types and the standard integer types, so reject e.g. _BitInt or overflow
+    // behavior types.
     if (!LHSType->getAs<BuiltinType>() || !RHSType->getAs<BuiltinType>())
       return QualType();
     return handleFixedPointConversion(*this, LHSType, RHSType);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to