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

>From 2b6df5fd8d81d1e41dadb019b963cfe097961f37 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Sat, 7 Feb 2026 04:46:28 +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.
we guard the entry points of the compiler (visitinitlist, visitcastexpr)
to emit an error opcode if the expression contains errors. this prevents
execution of invalid nodes (avoiding crash) while allowing compilation
of dead code containing errors.

we also update the Pointer class to handle global variables safely in
isInitialized and other metadata checks, preventing assertion failures
when accessing subobjects of globally-defined records/arrays.

fixes #175432
---
 clang/lib/AST/ByteCode/Compiler.cpp  |  6 +++
 clang/lib/AST/ByteCode/Pointer.cpp   | 18 ++++++---
 clang/lib/AST/ByteCode/Pointer.h     | 59 +++++++++++++++++++++++-----
 clang/test/AST/ByteCode/gh175432.cpp |  4 ++
 4 files changed, 71 insertions(+), 16 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..bddd8aae27c76 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 this->emitError(CE);
+
   const Expr *SubExpr = CE->getSubExpr();
 
   if (DiscardResult)
@@ -2184,6 +2187,9 @@ bool Compiler<Emitter>::visitCallArgs(ArrayRef<const Expr 
*> Args,
 
 template <class Emitter>
 bool Compiler<Emitter>::VisitInitListExpr(const InitListExpr *E) {
+  if (E->containsErrors())
+    return this->emitError(E);
+
   return this->visitInitList(E->inits(), E->getArrayFiller(), E);
 }
 
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp 
b/clang/lib/AST/ByteCode/Pointer.cpp
index fb9202c6d66c8..cf7209ddd74a4 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -448,10 +448,10 @@ bool Pointer::isInitialized() const {
   if (!isBlockPointer())
     return true;
 
-  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor) &&
-      Offset == BS.Base) {
+  if (isStatic() && BS.Base == sizeof(GlobalInlineDescriptor)) {
     const auto &GD = block()->getBlockDesc<GlobalInlineDescriptor>();
-    return GD.InitState == GlobalInitState::Initialized;
+    if (GD.InitState == GlobalInitState::Initialized)
+      return true;
   }
 
   assert(BS.Pointee && "Cannot check if null pointer was initialized");
@@ -462,6 +462,12 @@ bool Pointer::isInitialized() const {
 
   if (asBlockPointer().Base == 0)
     return true;
+
+  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor)) {
+    const auto &GD = block()->getBlockDesc<GlobalInlineDescriptor>();
+    return GD.InitState == GlobalInitState::Initialized;
+  }
+
   // Field has its bit in an inline descriptor.
   return getInlineDesc()->IsInitialized;
 }
@@ -476,10 +482,10 @@ bool Pointer::isElementInitialized(unsigned Index) const {
   if (isStatic() && BS.Base == 0)
     return true;
 
-  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor) &&
-      Offset == BS.Base) {
+  if (isStatic() && BS.Base == sizeof(GlobalInlineDescriptor)) {
     const auto &GD = block()->getBlockDesc<GlobalInlineDescriptor>();
-    return GD.InitState == GlobalInitState::Initialized;
+    if (GD.InitState == GlobalInitState::Initialized)
+      return true;
   }
 
   if (Desc->isPrimitiveArray()) {
diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index 2515b2fe56ab9..41fabe9ca165a 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -311,6 +311,8 @@ class Pointer {
 
   /// Returns a pointer to the object of which this pointer is a field.
   [[nodiscard]] Pointer getBase() const {
+    if (isRoot())
+      return *this;
     if (BS.Base == RootPtrMark) {
       assert(Offset == PastEndMark && "cannot get base of a block");
       return Pointer(BS.Pointee, BS.Base, 0);
@@ -407,10 +409,14 @@ class Pointer {
     return false;
   }
   bool inUnion() const {
-    if (isBlockPointer() && BS.Base >= sizeof(InlineDescriptor))
-      return getInlineDesc()->InUnion;
-    return false;
-  };
+    if (!isBlockPointer())
+      return false;
+    if (isRoot())
+      return false;
+    if (isStatic() && BS.Base == sizeof(GlobalInlineDescriptor))
+      return false;
+    return getInlineDesc()->InUnion;
+  }
 
   /// Checks if the structure is a primitive array.
   bool inPrimitiveArray() const {
@@ -433,6 +439,9 @@ class Pointer {
     if (inArray() && BP.Base != Offset)
       return true;
 
+    if (BP.Base == sizeof(GlobalInlineDescriptor) && isStatic())
+      return false;
+
     // Might be a narrow()'ed element in a composite array.
     // Check the inline descriptor.
     if (BP.Base >= sizeof(InlineDescriptor) && getInlineDesc()->IsArrayElement)
@@ -527,7 +536,11 @@ class Pointer {
   bool isMutable() const {
     if (!isBlockPointer())
       return false;
-    return !isRoot() && getInlineDesc()->IsFieldMutable;
+    if (isRoot())
+      return false;
+    if (isStatic() && BS.Base == sizeof(GlobalInlineDescriptor))
+      return false;
+    return getInlineDesc()->IsFieldMutable;
   }
 
   bool isWeak() const {
@@ -543,11 +556,25 @@ class Pointer {
   bool isActive() const {
     if (!isBlockPointer())
       return true;
-    return isRoot() || getInlineDesc()->IsActive;
+    if (isRoot())
+      return true;
+    if (isStatic() && BS.Base == sizeof(GlobalInlineDescriptor))
+      return true;
+    return getInlineDesc()->IsActive;
   }
   /// Checks if a structure is a base class.
-  bool isBaseClass() const { return isField() && getInlineDesc()->IsBase; }
+  bool isBaseClass() const {
+    if (isRoot())
+      return false;
+    if (isStatic() && BS.Base == sizeof(GlobalInlineDescriptor))
+      return false;
+    return isField() && getInlineDesc()->IsBase;
+  }
   bool isVirtualBaseClass() const {
+    if (isRoot())
+      return false;
+    if (isStatic() && BS.Base == sizeof(GlobalInlineDescriptor))
+      return false;
     return isField() && getInlineDesc()->IsVirtualBase;
   }
   /// Checks if the pointer points to a dummy value.
@@ -564,19 +591,31 @@ class Pointer {
   bool isConst() const {
     if (isIntegralPointer())
       return true;
-    return isRoot() ? getDeclDesc()->IsConst : getInlineDesc()->IsConst;
+    if (isRoot())
+      return getDeclDesc()->IsConst;
+    if (isStatic() && BS.Base == sizeof(GlobalInlineDescriptor))
+      return getDeclDesc()->IsConst;
+    return getInlineDesc()->IsConst;
   }
   bool isConstInMutable() const {
     if (!isBlockPointer())
       return false;
-    return isRoot() ? false : getInlineDesc()->IsConstInMutable;
+    if (isRoot())
+      return false;
+    if (isStatic() && BS.Base == sizeof(GlobalInlineDescriptor))
+      return false;
+    return isField() && getInlineDesc()->IsConstInMutable;
   }
 
   /// Checks if an object or a subfield is volatile.
   bool isVolatile() const {
     if (!isBlockPointer())
       return false;
-    return isRoot() ? getDeclDesc()->IsVolatile : getInlineDesc()->IsVolatile;
+    if (isRoot())
+      return getDeclDesc()->IsVolatile;
+    if (isStatic() && BS.Base == sizeof(GlobalInlineDescriptor))
+      return getDeclDesc()->IsVolatile;
+    return getInlineDesc()->IsVolatile;
   }
 
   /// Returns the declaration ID.
diff --git a/clang/test/AST/ByteCode/gh175432.cpp 
b/clang/test/AST/ByteCode/gh175432.cpp
new file mode 100644
index 0000000000000..c5ea6a072e7bd
--- /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 '(' for function-style cast or type construction}}
+static_assert(foo[0][0] == nullptr, ""); // expected-error {{constant 
expression}} expected-note {{initializer of 'foo' is unknown}}

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

Reply via email to