[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