https://github.com/Mr-Anyone created 
https://github.com/llvm/llvm-project/pull/154627

Check for missing VLA size expressions (e.g. in int a[*][10]) before evaluation 
to avoid crashes in _Countof and constant expression checks.

fixes #152826

>From bdf360400228106ef4e50677797d30e18a2bab19 Mon Sep 17 00:00:00 2001
From: Vincent <l...@viceroygroup.ca>
Date: Sat, 9 Aug 2025 23:07:30 +0800
Subject: [PATCH] [clang] Fix Variable Length Array `_Countof` Crash

Check for missing VLA size expressions (e.g. in int a[*][10])
before evaluation to avoid crashes in _Countof and constant
expression checks.

fixes #152826
---
 clang/docs/ReleaseNotes.rst         |  2 ++
 clang/lib/AST/ByteCode/Compiler.cpp |  4 +++-
 clang/lib/AST/ExprConstant.cpp      | 12 +++++++++++-
 clang/test/Sema/gh152826.c          |  6 ++++++
 4 files changed, 22 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/gh152826.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e88d68fa99664..df738db771e33 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -200,6 +200,8 @@ Bug Fixes in This Version
 -------------------------
 - Fix a crash when marco name is empty in ``#pragma push_macro("")`` or
   ``#pragma pop_macro("")``. (#GH149762).
+- Fix a crash in variable length array (e.g. int a[*]) function parameter type 
+  being used in `_Countof` expression. (#GH152826)
 - `-Wunreachable-code`` now diagnoses tautological or contradictory
   comparisons such as ``x != 0 || x != 1.0`` and ``x == 0 && x == 1.0`` on
   targets that treat ``_Float16``/``__fp16`` as native scalar types. Previously
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index e3235d34e230e..7881afc4bb6f5 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -2248,7 +2248,9 @@ bool Compiler<Emitter>::VisitUnaryExprOrTypeTraitExpr(
     assert(VAT);
     if (VAT->getElementType()->isArrayType()) {
       std::optional<APSInt> Res =
-          VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx);
+          VAT->getSizeExpr()
+              ? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
+              : std::nullopt;
       if (Res) {
         if (DiscardResult)
           return true;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 9c87a88899647..1d939cf9655d4 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15345,6 +15345,13 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
     const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
     assert(VAT);
     if (VAT->getElementType()->isArrayType()) {
+      // Variable array size expression could be missing (e.g. int a[*][10]) In
+      // that case, it can't be a constant expression
+      if (!VAT->getSizeExpr()) {
+        Info.FFDiag(E->getBeginLoc());
+        return false;
+      }
+
       std::optional<APSInt> Res =
           VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
       if (Res) {
@@ -17867,7 +17874,10 @@ static ICEDiag CheckICE(const Expr* E, const 
ASTContext &Ctx) {
         // it is an ICE or not.
         const auto *VAT = Ctx.getAsVariableArrayType(ArgTy);
         if (VAT->getElementType()->isArrayType())
-          return CheckICE(VAT->getSizeExpr(), Ctx);
+          // Variable array size expression could be missing (e.g. int 
a[*][10])
+          // In that case, it can't be a constant expression
+          return VAT->getSizeExpr() ? CheckICE(VAT->getSizeExpr(), Ctx)
+                                    : ICEDiag(IK_NotICE, E->getBeginLoc());
 
         // Otherwise, this is a regular VLA, which is definitely not an ICE.
         return ICEDiag(IK_NotICE, E->getBeginLoc());
diff --git a/clang/test/Sema/gh152826.c b/clang/test/Sema/gh152826.c
new file mode 100644
index 0000000000000..a7d5f0138ad5d
--- /dev/null
+++ b/clang/test/Sema/gh152826.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -std=c2y -verify %s
+// RUN: %clang_cc1 -std=c2y -verify -fexperimental-new-constant-interpreter %s
+// expected-no-diagnostics
+
+void gh152826(char (*a)[*][5], int (*x)[_Countof (*a)]);
+void more_likely_in_practice(unsigned long size_one, int (*a)[*][5], int 
b[_Countof(*a)]);

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to