[clang] [analyzer] Fix zero-init regression in RegionStore (PR #189319)

via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 29 22:58:59 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Chandana Mudda (chandmudda)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/189319.diff


2 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Core/RegionStore.cpp (+7-5) 
- (added) clang/test/Analysis/compile-and-analyze-regression.cpp (+16) 


``````````diff
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;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/189319


More information about the cfe-commits mailing list