https://github.com/Serosh-commits created 
https://github.com/llvm/llvm-project/pull/180261

this fixes an assertion failure where the interpreter would crash on invalid 
initializer lists 
The problem was that we kept processing expressions even after they were 
flagged with errors. this led to bad state and the eventual crash so i  added 
checks for `containsErrors()` in compiler.cpp and other entry points so we bail 
out early instead of asserting.
fixes #175432

>From d7181759082c06607e8214d7feba0cb9840ef137 Mon Sep 17 00:00:00 2001
From: Serosh <[email protected]>
Date: Fri, 6 Feb 2026 23:35:24 +0530
Subject: [PATCH] [clang][bytecode] Fix assertion failure on invalid init list
 (GH175432)

This patch fixes a crash/assertion failure in the new constant interpreter
when handling invalid initializer lists or expressions containing errors.

The interpreter was attempting to evaluate/visit AST nodes that had been
flagged with errors by the frontend (e.g., e->containsErrors()), leading
to invalid state (such as unexpected pointer bases) and subsequent
assertions in Pointer.cpp.

We now guard the entry points of the Compiler (visit, visitInitList,
VisitCastExpr, etc.) to immediately return false if the expression
contains errors, ensuring we bail out gracefully instead of asserting.

Fixes #175432
---
 clang/lib/AST/ByteCode/Compiler.cpp  | 23 +++++++++++++++++++++--
 clang/test/AST/ByteCode/gh175432.cpp |  4 ++++
 2 files changed, 25 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/AST/ByteCode/gh175432.cpp

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index a0138c402e143..a5a9f1e2e440d 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -211,6 +211,9 @@ template <class Emitter> class LocOverrideScope final {
 
 template <class Emitter>
 bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
+  if (CE->containsErrors())
+    return false;
+
   const Expr *SubExpr = CE->getSubExpr();
 
   if (DiscardResult)
@@ -477,8 +480,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
     return this->delegate(SubExpr);
 
   case CK_BitCast: {
-    if (CE->containsErrors())
-      return false;
     QualType CETy = CE->getType();
     // Reject bitcasts to atomic types.
     if (CETy->isAtomicType()) {
@@ -1836,6 +1837,9 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const 
ArraySubscriptExpr *E) {
 template <class Emitter>
 bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
                                       const Expr *ArrayFiller, const Expr *E) {
+  if (E->containsErrors())
+    return false;
+
   InitLinkScope<Emitter> ILS(this, InitLink::InitList());
 
   QualType QT = E->getType();
@@ -4264,12 +4268,18 @@ bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr 
*E) {
 }
 
 template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
+  if (E->containsErrors())
+    return false;
+
   OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
                              /*NewInitializing=*/false, /*ToLValue=*/false);
   return this->Visit(E);
 }
 
 template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) {
+  if (E->containsErrors())
+    return false;
+
   // We're basically doing:
   // OptionScope<Emitter> Scope(this, DicardResult, Initializing, ToLValue);
   // but that's unnecessary of course.
@@ -4302,6 +4312,9 @@ static const Expr *stripDerivedToBaseCasts(const Expr *E) 
{
 }
 
 template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
+  if (E->containsErrors())
+    return false;
+
   if (E->getType().isNull())
     return false;
 
@@ -4330,6 +4343,9 @@ template <class Emitter> bool 
Compiler<Emitter>::visit(const Expr *E) {
 
 template <class Emitter>
 bool Compiler<Emitter>::visitInitializer(const Expr *E) {
+  if (E->containsErrors())
+    return false;
+
   assert(!canClassify(E->getType()));
 
   OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
@@ -4338,6 +4354,9 @@ bool Compiler<Emitter>::visitInitializer(const Expr *E) {
 }
 
 template <class Emitter> bool Compiler<Emitter>::visitAsLValue(const Expr *E) {
+  if (E->containsErrors())
+    return false;
+
   OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
                              /*NewInitializing=*/false, /*ToLValue=*/true);
   return this->Visit(E);
diff --git a/clang/test/AST/ByteCode/gh175432.cpp 
b/clang/test/AST/ByteCode/gh175432.cpp
new file mode 100644
index 0000000000000..9433a83c76f56
--- /dev/null
+++ b/clang/test/AST/ByteCode/gh175432.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s
+
+constexpr const int *foo[][2] = { {nullptr, int}, }; // expected-error 
{{expected expression}}
+static_assert(foo[0][0] == nullptr, "");

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

Reply via email to