[clang] [analyzer] Fix zero-init regression in RegionStore (PR #189319)
Chandana Mudda via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 29 22:58:12 PDT 2026
https://github.com/chandmudda created https://github.com/llvm/llvm-project/pull/189319
Narrow the new setImplicitDefaultValue() guard so existing default bindings are preserved only for aggregate-like cases.
The previous change was too broad and regressed normal zero-initialization, causing new int[10]{} to be modeled as undefined and emit a garbage-value warning instead of the expected analyzer reports.
>From 8c4a3c6fc275b5d712309dc5e37b3e95455ae222 Mon Sep 17 00:00:00 2001
From: Chandana Mudda <quic_csinderi at quicinc.com>
Date: Sun, 29 Mar 2026 22:49:14 -0700
Subject: [PATCH] [analyzer] Fix zero-init regression in RegionStore
Narrow the new setImplicitDefaultValue() guard so existing default
bindings are preserved only for aggregate-like cases.
The previous change was too broad and regressed normal zero-initialization,
causing new int[10]{} to be modeled as undefined and emit a garbage-value
warning instead of the expected analyzer reports.
---
clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 12 +++++++-----
.../Analysis/compile-and-analyze-regression.cpp | 16 ++++++++++++++++
2 files changed, 23 insertions(+), 5 deletions(-)
create mode 100644 clang/test/Analysis/compile-and-analyze-regression.cpp
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index 6ec66298e8c45..ea636d41353dc 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -2566,11 +2566,13 @@ RegionStoreManager::setImplicitDefaultValue(LimitedRegionBindingsConstRef B,
if (B.hasExhaustedBindingLimit())
return B;
- // Prefer to keep the previous default binding if we had one; that is likely a
- // better choice than setting some arbitrary new default value.
- // This isn't ideal (more of a hack), but better than dropping the more
- // accurate default binding.
- if (B.getDefaultBinding(R).has_value()) {
+ // Preserve an existing aggregate default binding. This handles partially
+ // initialized union-containing aggregates where bindAggregate() may already
+ // have installed a more precise default value at offset 0. Still allow
+ // implicit defaults for scalars and pointers so regular zero-initialization
+ // continues to work, e.g. for `new int[10]{}`.
+ if ((T->isStructureOrClassType() || T->isArrayType() || T->isUnionType()) &&
+ B.getDefaultBinding(R).has_value()) {
return B;
}
diff --git a/clang/test/Analysis/compile-and-analyze-regression.cpp b/clang/test/Analysis/compile-and-analyze-regression.cpp
new file mode 100644
index 0000000000000..ec550800e2fa2
--- /dev/null
+++ b/clang/test/Analysis/compile-and-analyze-regression.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang --analyze %s 2>&1 | FileCheck %s
+
+// CHECK: Address of stack memory associated with local variable 'i'
+// CHECK: is still referred to by the global variable 'gp' upon returning
+// CHECK: to the caller. This will be a dangling reference
+// CHECK: Potential leak of memory pointed to by 'p'
+
+unsigned int *gp;
+int foo(unsigned int argc) {
+ int *p = new int[10]{};
+ unsigned int i = 100;
+ gp = &i;
+ if (argc > *p)
+ return i;
+ return *p;
+}
More information about the cfe-commits
mailing list