[clang] [clang] Fix Variable Length Array `_Countof` Crash (PR #154627)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 25 08:33:06 PDT 2025
https://github.com/Mr-Anyone updated https://github.com/llvm/llvm-project/pull/154627
>From 88d32278e6cbb0f25e752849ed8271c658acf3aa Mon Sep 17 00:00:00 2001
From: Vincent <llvm at viceroygroup.ca>
Date: Sat, 9 Aug 2025 23:07:30 +0800
Subject: [PATCH 1/3] [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 fe1dd15c6f885..1ec2f491250ea 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -222,6 +222,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 a03e64fcffde2..fd7488b2b239a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15367,6 +15367,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) {
@@ -17904,7 +17911,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)]);
>From cd9e0fb011319931422aa5b5e32450791fd05b0c Mon Sep 17 00:00:00 2001
From: Vincent <llvm at viceroygroup.ca>
Date: Thu, 21 Aug 2025 13:42:46 -0400
Subject: [PATCH 2/3] Address Comments
---
clang/docs/ReleaseNotes.rst | 4 ++--
clang/lib/AST/ExprConstant.cpp | 4 ++--
clang/test/Sema/gh152826.c | 1 +
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1ec2f491250ea..ad1f57db9c239 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -222,8 +222,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)
+- 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/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index fd7488b2b239a..96ada8769a8e1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15368,7 +15368,7 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
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
+ // that case, it can't be a constant expression.
if (!VAT->getSizeExpr()) {
Info.FFDiag(E->getBeginLoc());
return false;
@@ -17912,7 +17912,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
const auto *VAT = Ctx.getAsVariableArrayType(ArgTy);
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
+ // In that case, it can't be a constant expression.
return VAT->getSizeExpr() ? CheckICE(VAT->getSizeExpr(), Ctx)
: ICEDiag(IK_NotICE, E->getBeginLoc());
diff --git a/clang/test/Sema/gh152826.c b/clang/test/Sema/gh152826.c
index a7d5f0138ad5d..a1d197ca5721a 100644
--- a/clang/test/Sema/gh152826.c
+++ b/clang/test/Sema/gh152826.c
@@ -4,3 +4,4 @@
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)]);
+void f(int (*x)[*][1][*][2][*][*][3][*], int q[_Countof(*x)]);
>From d4190aa9998c45906b14e28efe752d358f0b472e Mon Sep 17 00:00:00 2001
From: Vincent <llvm at viceroygroup.ca>
Date: Mon, 25 Aug 2025 11:32:51 -0400
Subject: [PATCH 3/3] Formatting
---
clang/docs/ReleaseNotes.rst | 2 +-
clang/test/Sema/gh152826.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ad1f57db9c239..2c6f8ea6e874d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -223,7 +223,7 @@ 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)
+ 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/test/Sema/gh152826.c b/clang/test/Sema/gh152826.c
index a1d197ca5721a..1234d80bd0867 100644
--- a/clang/test/Sema/gh152826.c
+++ b/clang/test/Sema/gh152826.c
@@ -2,6 +2,6 @@
// RUN: %clang_cc1 -std=c2y -verify -fexperimental-new-constant-interpreter %s
// expected-no-diagnostics
-void gh152826(char (*a)[*][5], int (*x)[_Countof (*a)]);
+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)]);
void f(int (*x)[*][1][*][2][*][*][3][*], int q[_Countof(*x)]);
More information about the cfe-commits
mailing list