https://github.com/PrabbyDD updated 
https://github.com/llvm/llvm-project/pull/195945

>From 36ce4b83c0c674cdc6439f49a90c59ee5bdc613a Mon Sep 17 00:00:00 2001
From: PrabbyDD <[email protected]>
Date: Tue, 5 May 2026 14:16:55 -0700
Subject: [PATCH 1/5] Fix crash by checking for the type signage before
 entering getCorrespondingSignedType()

---
 clang/docs/ReleaseNotes.rst                |  1 +
 clang/lib/Sema/SemaExpr.cpp                | 18 +++++++++++-------
 clang/test/Sema/va_arg_enum_underlying.cpp | 15 +++++++++++++++
 3 files changed, 27 insertions(+), 7 deletions(-)
 create mode 100644 clang/test/Sema/va_arg_enum_underlying.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ec64c2008d89b..f01a73739d8e0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -519,6 +519,7 @@ Bug Fixes in This Version
 - Clang now emits an error for friend declarations of lambda members. 
(#GH26540)
 - Fixed a crash caused by lambda capture handling in delayed default 
arguments. (#GH176534)
 - Fixed a crash when parsing invalid ``static_assert`` declarations with 
string-literal messages (#GH187690).
+- Fixed an assert/crash in ``__builtin_va_arg`` when the argument type is an 
enum without a correspoding signed type (#GH191698).
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c494669420282..2712acb0d0936 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17314,13 +17314,17 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation 
BuiltinLoc,
       if (!PromoteType.isNull() && !UnderlyingType->isBooleanType() &&
           PromoteType->isUnsignedIntegerType() !=
               UnderlyingType->isUnsignedIntegerType()) {
-        UnderlyingType =
-            UnderlyingType->isUnsignedIntegerType()
-                ? Context.getCorrespondingSignedType(UnderlyingType)
-                : Context.getCorrespondingUnsignedType(UnderlyingType);
-        if (Context.typesAreCompatible(PromoteType, UnderlyingType,
-                                       /*CompareUnqualified*/ true))
-          PromoteType = QualType();
+
+        if (!UnderlyingType->isUnsignedIntegerType() ||
+            UnderlyingType->hasSignedIntegerRepresentation()) {
+          UnderlyingType =
+              UnderlyingType->isUnsignedIntegerType()
+                  ? Context.getCorrespondingSignedType(UnderlyingType)
+                  : Context.getCorrespondingUnsignedType(UnderlyingType);
+          if (Context.typesAreCompatible(PromoteType, UnderlyingType,
+                                         /*CompareUnqualified*/ true))
+            PromoteType = QualType();
+        }
       }
     }
     if (TInfo->getType()->isSpecificBuiltinType(BuiltinType::Float))
diff --git a/clang/test/Sema/va_arg_enum_underlying.cpp 
b/clang/test/Sema/va_arg_enum_underlying.cpp
new file mode 100644
index 0000000000000..e4962f4e1326e
--- /dev/null
+++ b/clang/test/Sema/va_arg_enum_underlying.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+__builtin_va_list ap;
+
+void foo() {
+  enum E1 : char16_t {};
+  enum E2 : char32_t {};
+  enum E3 : unsigned char {};
+  enum E4 : wchar_t {};
+
+  (void)__builtin_va_arg(ap, E1); // expected-warning {{second argument to 
'va_arg' is of promotable type}}
+  (void)__builtin_va_arg(ap, E2); // expected-warning {{second argument to 
'va_arg' is of promotable type}}
+  (void)__builtin_va_arg(ap, E3); // expected-warning {{second argument to 
'va_arg' is of promotable type}}
+  (void)__builtin_va_arg(ap, E4); // expected-warning {{second argument to 
'va_arg' is of promotable type}}
+}

>From 14b664ec4a3b1251679b71c93f3eca3e37168d8f Mon Sep 17 00:00:00 2001
From: PrabbyDD <[email protected]>
Date: Tue, 5 May 2026 14:46:42 -0700
Subject: [PATCH 2/5] adding an expected warning to varargs test since we now
 emit that

---
 clang/test/SemaCXX/varargs.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/SemaCXX/varargs.cpp b/clang/test/SemaCXX/varargs.cpp
index 1e5920a8728d3..c84d765296e88 100644
--- a/clang/test/SemaCXX/varargs.cpp
+++ b/clang/test/SemaCXX/varargs.cpp
@@ -31,7 +31,7 @@ void record_context(int a, ...) {
 // Ensure the correct behavior for promotable type UB checking.
 void promotable(int a, ...) {
   enum Unscoped1 { One = 0x7FFFFFFF };
-  (void)__builtin_va_arg(ap, Unscoped1); // ok
+  (void)__builtin_va_arg(ap, Unscoped1); // expected-warning {{second argument 
to 'va_arg' is of promotable type}}
 
   enum Unscoped2 { Two = 0xFFFFFFFF };
   (void)__builtin_va_arg(ap, Unscoped2); // ok

>From f7d982d99aca247f7bb5cb0f9d58cde25d82a985 Mon Sep 17 00:00:00 2001
From: PrabbyDD <[email protected]>
Date: Wed, 6 May 2026 14:20:16 -0700
Subject: [PATCH 3/5] hard guarding against the problematic types...and
 reverting expected warning in varargs test.

---
 clang/lib/Sema/SemaExpr.cpp    | 58 +++++++++++++++++++---------------
 clang/test/SemaCXX/varargs.cpp |  2 +-
 2 files changed, 33 insertions(+), 27 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2712acb0d0936..ac60fe19afb58 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -12521,28 +12521,6 @@ static void diagnoseTautologicalComparison(Sema &S, 
SourceLocation Loc,
     AlwaysEqual, // std::strong_ordering::equal from operator<=>
   };
 
-  // C++1a [array.comp]:
-  //   Equality and relational comparisons ([expr.eq], [expr.rel]) between two
-  //   operands of array type.
-  // C++2a [depr.array.comp]:
-  //   Equality and relational comparisons ([expr.eq], [expr.rel]) between two
-  //   operands of array type are deprecated.
-  if (S.getLangOpts().CPlusPlus && LHSStripped->getType()->isArrayType() &&
-      RHSStripped->getType()->isArrayType()) {
-    auto IsDeprArrayComparionIgnored =
-        S.getDiagnostics().isIgnored(diag::warn_depr_array_comparison, Loc);
-    auto DiagID = S.getLangOpts().CPlusPlus26
-                      ? diag::warn_array_comparison_cxx26
-                  : !S.getLangOpts().CPlusPlus20 || IsDeprArrayComparionIgnored
-                      ? diag::warn_array_comparison
-                      : diag::warn_depr_array_comparison;
-    S.Diag(Loc, DiagID) << LHS->getSourceRange() << RHS->getSourceRange()
-                        << LHSStripped->getType() << RHSStripped->getType();
-    // Carry on to produce the tautological comparison warning, if this
-    // expression is potentially-evaluated, we can resolve the array to a
-    // non-weak declaration, and so on.
-  }
-
   if (!LHS->getBeginLoc().isMacroID() && !RHS->getBeginLoc().isMacroID()) {
     if (Expr::isSameComparisonOperand(LHS, RHS)) {
       unsigned Result;
@@ -12860,6 +12838,31 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, 
ExprResult &RHS,
     return Ty->isPointerType() || Ty->isMemberPointerType();
   };
 
+  // C++1a [array.comp]:
+  //   Equality and relational comparisons ([expr.eq], [expr.rel]) between two
+  //   operands of array type.
+  // C++2a [depr.array.comp]:
+  //   Equality and relational comparisons ([expr.eq], [expr.rel]) between two
+  //   operands of array type are deprecated.
+  Expr *LHSStripped = LHS.get()->IgnoreParenImpCasts();
+  Expr *RHSStripped = RHS.get()->IgnoreParenImpCasts();
+  if (getLangOpts().CPlusPlus && LHSStripped->getType()->isArrayType() &&
+      RHSStripped->getType()->isArrayType()) {
+
+    auto IsDeprArrayComparionIgnored =
+        getDiagnostics().isIgnored(diag::warn_depr_array_comparison, Loc);
+    auto DiagID = getLangOpts().CPlusPlus26 ? diag::warn_array_comparison_cxx26
+                  : !getLangOpts().CPlusPlus20 || IsDeprArrayComparionIgnored
+                      ? diag::warn_array_comparison
+                      : diag::warn_depr_array_comparison;
+    Diag(Loc, DiagID) << LHS.get()->getSourceRange()
+                      << RHS.get()->getSourceRange() << LHSStripped->getType()
+                      << RHSStripped->getType();
+    if (getLangOpts().CPlusPlus26) {
+      return QualType();
+    }
+  }
+
   // C++2a [expr.spaceship]p6: If at least one of the operands is of pointer
   // type, array-to-pointer, ..., conversions are performed on both operands to
   // bring them to their composite type.
@@ -17315,14 +17318,17 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation 
BuiltinLoc,
           PromoteType->isUnsignedIntegerType() !=
               UnderlyingType->isUnsignedIntegerType()) {
 
-        if (!UnderlyingType->isUnsignedIntegerType() ||
-            UnderlyingType->hasSignedIntegerRepresentation()) {
+        // Because char16_t and char32_t have no corresponding signed type,
+        // calling getCorrespondingSignedType on them would assert. Guard
+        // against this.
+        const auto *BT = UnderlyingType->getAs<BuiltinType>();
+        if (!BT || (BT->getKind() != BuiltinType::Char16 &&
+                    BT->getKind() != BuiltinType::Char32)) {
           UnderlyingType =
               UnderlyingType->isUnsignedIntegerType()
                   ? Context.getCorrespondingSignedType(UnderlyingType)
                   : Context.getCorrespondingUnsignedType(UnderlyingType);
-          if (Context.typesAreCompatible(PromoteType, UnderlyingType,
-                                         /*CompareUnqualified*/ true))
+          if (Context.typesAreCompatible(PromoteType, UnderlyingType, true))
             PromoteType = QualType();
         }
       }
diff --git a/clang/test/SemaCXX/varargs.cpp b/clang/test/SemaCXX/varargs.cpp
index c84d765296e88..1e5920a8728d3 100644
--- a/clang/test/SemaCXX/varargs.cpp
+++ b/clang/test/SemaCXX/varargs.cpp
@@ -31,7 +31,7 @@ void record_context(int a, ...) {
 // Ensure the correct behavior for promotable type UB checking.
 void promotable(int a, ...) {
   enum Unscoped1 { One = 0x7FFFFFFF };
-  (void)__builtin_va_arg(ap, Unscoped1); // expected-warning {{second argument 
to 'va_arg' is of promotable type}}
+  (void)__builtin_va_arg(ap, Unscoped1); // ok
 
   enum Unscoped2 { Two = 0xFFFFFFFF };
   (void)__builtin_va_arg(ap, Unscoped2); // ok

>From 45dd8500072c93a4ca6651b78954e000bab7489f Mon Sep 17 00:00:00 2001
From: PrabbyDD <[email protected]>
Date: Wed, 6 May 2026 14:42:40 -0700
Subject: [PATCH 4/5] not sure why my PRs got mixed up

---
 clang/lib/Sema/SemaExpr.cpp | 48 +++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 26 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ac60fe19afb58..4e0b7387dc008 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -12521,6 +12521,28 @@ static void diagnoseTautologicalComparison(Sema &S, 
SourceLocation Loc,
     AlwaysEqual, // std::strong_ordering::equal from operator<=>
   };
 
+  // C++1a [array.comp]:
+  //   Equality and relational comparisons ([expr.eq], [expr.rel]) between two
+  //   operands of array type.
+  // C++2a [depr.array.comp]:
+  //   Equality and relational comparisons ([expr.eq], [expr.rel]) between two
+  //   operands of array type are deprecated.
+  if (S.getLangOpts().CPlusPlus && LHSStripped->getType()->isArrayType() &&
+      RHSStripped->getType()->isArrayType()) {
+    auto IsDeprArrayComparionIgnored =
+        S.getDiagnostics().isIgnored(diag::warn_depr_array_comparison, Loc);
+    auto DiagID = S.getLangOpts().CPlusPlus26
+                      ? diag::warn_array_comparison_cxx26
+                  : !S.getLangOpts().CPlusPlus20 || IsDeprArrayComparionIgnored
+                      ? diag::warn_array_comparison
+                      : diag::warn_depr_array_comparison;
+    S.Diag(Loc, DiagID) << LHS->getSourceRange() << RHS->getSourceRange()
+                        << LHSStripped->getType() << RHSStripped->getType();
+    // Carry on to produce the tautological comparison warning, if this
+    // expression is potentially-evaluated, we can resolve the array to a
+    // non-weak declaration, and so on.
+  }
+
   if (!LHS->getBeginLoc().isMacroID() && !RHS->getBeginLoc().isMacroID()) {
     if (Expr::isSameComparisonOperand(LHS, RHS)) {
       unsigned Result;
@@ -12838,31 +12860,6 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, 
ExprResult &RHS,
     return Ty->isPointerType() || Ty->isMemberPointerType();
   };
 
-  // C++1a [array.comp]:
-  //   Equality and relational comparisons ([expr.eq], [expr.rel]) between two
-  //   operands of array type.
-  // C++2a [depr.array.comp]:
-  //   Equality and relational comparisons ([expr.eq], [expr.rel]) between two
-  //   operands of array type are deprecated.
-  Expr *LHSStripped = LHS.get()->IgnoreParenImpCasts();
-  Expr *RHSStripped = RHS.get()->IgnoreParenImpCasts();
-  if (getLangOpts().CPlusPlus && LHSStripped->getType()->isArrayType() &&
-      RHSStripped->getType()->isArrayType()) {
-
-    auto IsDeprArrayComparionIgnored =
-        getDiagnostics().isIgnored(diag::warn_depr_array_comparison, Loc);
-    auto DiagID = getLangOpts().CPlusPlus26 ? diag::warn_array_comparison_cxx26
-                  : !getLangOpts().CPlusPlus20 || IsDeprArrayComparionIgnored
-                      ? diag::warn_array_comparison
-                      : diag::warn_depr_array_comparison;
-    Diag(Loc, DiagID) << LHS.get()->getSourceRange()
-                      << RHS.get()->getSourceRange() << LHSStripped->getType()
-                      << RHSStripped->getType();
-    if (getLangOpts().CPlusPlus26) {
-      return QualType();
-    }
-  }
-
   // C++2a [expr.spaceship]p6: If at least one of the operands is of pointer
   // type, array-to-pointer, ..., conversions are performed on both operands to
   // bring them to their composite type.
@@ -17332,7 +17329,6 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation 
BuiltinLoc,
             PromoteType = QualType();
         }
       }
-    }
     if (TInfo->getType()->isSpecificBuiltinType(BuiltinType::Float))
       PromoteType = Context.DoubleTy;
     if (!PromoteType.isNull())

>From 20d332f7a6aea2c8470ca23526f5f02765a7f724 Mon Sep 17 00:00:00 2001
From: PrabbyDD <[email protected]>
Date: Wed, 6 May 2026 14:51:26 -0700
Subject: [PATCH 5/5] always remember to re run the tests locally so you dont
 forget the curly brace

---
 clang/lib/Sema/SemaExpr.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 4e0b7387dc008..51aa19f830ae3 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17329,6 +17329,7 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation 
BuiltinLoc,
             PromoteType = QualType();
         }
       }
+    }
     if (TInfo->getType()->isSpecificBuiltinType(BuiltinType::Float))
       PromoteType = Context.DoubleTy;
     if (!PromoteType.isNull())

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

Reply via email to