[clang] [clang-tools-extra] [clang][ASTMatchers] Fix `hasArraySize` crash without a size expression (PR #215082)
MiaoMing Chen via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 9 06:00:47 PDT 2026
https://github.com/chenmiaoming updated https://github.com/llvm/llvm-project/pull/215082
>From 3ca8576afc8dc0a55000f211666c564f5073f9df Mon Sep 17 00:00:00 2001
From: MiaoMing Chen <miaomingc at stumail.nwu.edu.cn>
Date: Sun, 9 Aug 2026 14:14:02 +0800
Subject: [PATCH 1/2] [clang][ASTMatchers] Fix `hasArraySize` crash without a
size expression
CXXNewExpr::getArraySize() returns std::nullopt even when isArray() is
true, e.g. when there is no array size expression, as in 'new int[]()'.
The hasArraySize matcher dereferenced the optional unconditionally,
triggering undefined behavior (an assertion failure in assert-enabled
builds). Check the optional for engagement before matching.
Since getArraySize() already returns std::nullopt when isArray() is
false, the redundant isArray() check can be dropped.
Add a clang-tidy regression test that runs clang-tidy on a translation
unit containing 'new int[]()', which emits a compiler diagnostic but
must not crash the tool, and document the fix in the release notes.
Fixes #214281
---
clang-tools-extra/docs/ReleaseNotes.md | 4 ++++
.../misplaced-operator-in-strlen-in-alloc-no-crash.cpp | 4 ++++
clang/include/clang/ASTMatchers/ASTMatchers.h | 4 ++--
3 files changed, 10 insertions(+), 2 deletions(-)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/misplaced-operator-in-strlen-in-alloc-no-crash.cpp
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 5ded07934d906..4fc25558ae42a 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -102,6 +102,10 @@ infrastructure are described first, followed by tool-specific sections.
#### Changes in existing checks
+- Fixed a crash in {doc}`bugprone-misplaced-operator-in-strlen-in-alloc
+ <clang-tidy/checks/bugprone/misplaced-operator-in-strlen-in-alloc>` when
+ checking an array new expression without a size expression.
+
- Fixed a crash in {doc}`bugprone-std-namespace-modification
<clang-tidy/checks/bugprone/std-namespace-modification>` when checking
lambda closure types used as template arguments.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/misplaced-operator-in-strlen-in-alloc-no-crash.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/misplaced-operator-in-strlen-in-alloc-no-crash.cpp
new file mode 100644
index 0000000000000..c7b60100e0763
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/misplaced-operator-in-strlen-in-alloc-no-crash.cpp
@@ -0,0 +1,4 @@
+// RUN: %check_clang_tidy -expect-clang-tidy-error %s bugprone-misplaced-operator-in-strlen-in-alloc %t
+
+void *f() { return new int[](); }
+// CHECK-MESSAGES: :[[@LINE-1]]:24: error: cannot determine allocated array size from initializer [clang-diagnostic-error]
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 02d52b51a45c9..c168937d3641c 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -8652,8 +8652,8 @@ AST_MATCHER_P(CXXNewExpr, hasAnyPlacementArg, internal::Matcher<Expr>,
/// cxxNewExpr(hasArraySize(integerLiteral(equals(10))))
/// matches the expression 'new MyClass[10]'.
AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher<Expr>, InnerMatcher) {
- return Node.isArray() && *Node.getArraySize() &&
- InnerMatcher.matches(**Node.getArraySize(), Finder, Builder);
+ const auto ArraySize = Node.getArraySize();
+ return ArraySize && InnerMatcher.matches(**ArraySize, Finder, Builder);
}
/// Matches a class declaration that is defined.
>From 0e77d8647a417e388a4a28719c6966f78fdc9143 Mon Sep 17 00:00:00 2001
From: MiaoMing Chen <miaomingc at stumail.nwu.edu.cn>
Date: Sun, 9 Aug 2026 20:56:30 +0800
Subject: [PATCH 2/2] fixup! [clang][ASTMatchers] Fix `hasArraySize` crash
without a size expression
---
.../misplaced-operator-in-strlen-in-alloc-no-crash.cpp | 4 ++++
clang/include/clang/ASTMatchers/ASTMatchers.h | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/misplaced-operator-in-strlen-in-alloc-no-crash.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/misplaced-operator-in-strlen-in-alloc-no-crash.cpp
index c7b60100e0763..899eb1eee0994 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/misplaced-operator-in-strlen-in-alloc-no-crash.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/misplaced-operator-in-strlen-in-alloc-no-crash.cpp
@@ -2,3 +2,7 @@
void *f() { return new int[](); }
// CHECK-MESSAGES: :[[@LINE-1]]:24: error: cannot determine allocated array size from initializer [clang-diagnostic-error]
+
+template <int... Is> void g() {
+ new int[]{Is...};
+}
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index c168937d3641c..43cbeb3b40eac 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -8652,7 +8652,7 @@ AST_MATCHER_P(CXXNewExpr, hasAnyPlacementArg, internal::Matcher<Expr>,
/// cxxNewExpr(hasArraySize(integerLiteral(equals(10))))
/// matches the expression 'new MyClass[10]'.
AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher<Expr>, InnerMatcher) {
- const auto ArraySize = Node.getArraySize();
+ const std::optional<const Expr *> ArraySize = Node.getArraySize();
return ArraySize && InnerMatcher.matches(**ArraySize, Finder, Builder);
}
More information about the cfe-commits
mailing list