summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2017-12-21 18:43:02 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2017-12-21 18:43:02 +0000
commit9d3ca9a5ae35ff272b31eb238caf0950ee072284 (patch)
tree7d9f6ff25f95cfd15710d4c850d1cd0c66449451 /clang/lib/StaticAnalyzer/Core/RegionStore.cpp
parent4de5bb093c9d68fa97b60ce542020993f183af39 (diff)
downloadbcm5719-llvm-9d3ca9a5ae35ff272b31eb238caf0950ee072284.tar.gz
bcm5719-llvm-9d3ca9a5ae35ff272b31eb238caf0950ee072284.zip
[analyzer] Fix zero-initialization of stack VLAs under ObjC ARC.
Using ARC, strong, weak, and autoreleasing stack variables are implicitly initialized with nil. This includes variable-length arrays of Objective-C object pointers. However, in the analyzer we don't zero-initialize them. We used to, but it accidentally regressed after r289618. Under ARC, the array variable's initializer within DeclStmt is an ImplicitValueInitExpr. Environment doesn't maintain any bindings for this expression kind - instead it always knows that it's a known constant (0 in our case), so it just returns the known value by calling SValBuilder::makeZeroVal() (see EnvironmentManager::getSVal(). Commit r289618 had introduced reasonable behavior of SValBuilder::makeZeroVal() for the arrays, which produces a zero-length compoundVal{}. When such value is bound to arrays, in RegionStoreManager::bindArray() "remaining" items in the array are default-initialized with zero, as in RegionStoreManager::setImplicitDefaultValue(). The similar mechanism works when an array is initialized by an initializer list that is too short, eg. int a[3] = { 1, 2 }; would result in a[2] initialized with 0. However, in case of variable-length arrays it didn't know if any more items need to be added, because, well, the length is variable. Add the default binding anyway, regardless of how many actually need to be added. We don't really care how many, because the default binding covers the whole array anyway. Differential Revision: https://reviews.llvm.org/D41478 rdar://problem/35477763 llvm-svn: 321290
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/RegionStore.cpp7
1 files changed, 4 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index 7f2a481c6b0..e2e69bb28ec 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -2132,9 +2132,10 @@ RegionStoreManager::bindArray(RegionBindingsConstRef B,
NewB = bind(NewB, loc::MemRegionVal(ER), *VI);
}
- // If the init list is shorter than the array length, set the
- // array default value.
- if (Size.hasValue() && i < Size.getValue())
+ // If the init list is shorter than the array length (or the array has
+ // variable length), set the array default value. Values that are already set
+ // are not overwritten.
+ if (!Size.hasValue() || i < Size.getValue())
NewB = setImplicitDefaultValue(NewB, R, ElementTy);
return NewB;
OpenPOWER on IntegriCloud