[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