https://github.com/chandmudda updated https://github.com/llvm/llvm-project/pull/189319
>From 8c4a3c6fc275b5d712309dc5e37b3e95455ae222 Mon Sep 17 00:00:00 2001 From: Chandana Mudda <[email protected]> Date: Sun, 29 Mar 2026 22:49:14 -0700 Subject: [PATCH 1/2] [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; +} >From 0d83f21a1d46ebb940b1b3c0b3700b57cc827016 Mon Sep 17 00:00:00 2001 From: Chandana Mudda <[email protected]> Date: Thu, 2 Apr 2026 23:18:31 -0700 Subject: [PATCH 2/2] [analyzer] Reduced test case Reduced test case to make it more aligned with expectations. --- .../compile-and-analyze-regression.cpp | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/clang/test/Analysis/compile-and-analyze-regression.cpp b/clang/test/Analysis/compile-and-analyze-regression.cpp index ec550800e2fa2..dea77bb02a403 100644 --- a/clang/test/Analysis/compile-and-analyze-regression.cpp +++ b/clang/test/Analysis/compile-and-analyze-regression.cpp @@ -1,16 +1,13 @@ -// RUN: %clang --analyze %s 2>&1 | FileCheck %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection %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' +// CHECK: TRUE +// CHECK-NOT: garbage +// CHECK-NOT: uninitialized -unsigned int *gp; -int foo(unsigned int argc) { +void clang_analyzer_eval(int); + +void test_zero_initialized_new_array() { int *p = new int[10]{}; - unsigned int i = 100; - gp = &i; - if (argc > *p) - return i; - return *p; + clang_analyzer_eval(*p == 0); + delete[] p; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
