diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2017-12-21 18:43:02 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2017-12-21 18:43:02 +0000 |
commit | 53ad81a8b50d9e94636a15b4ede32986450a85e0 (patch) | |
tree | c4ef8771d9d38393eb3ca2654a0aa30627002d4d /test/Analysis | |
parent | a89e36b23afdebef1719dda8a994ff81ee0e3113 (diff) |
[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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@321290 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Analysis')
-rw-r--r-- | test/Analysis/arc-zero-init.m | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/test/Analysis/arc-zero-init.m b/test/Analysis/arc-zero-init.m new file mode 100644 index 0000000000..de1e978cd0 --- /dev/null +++ b/test/Analysis/arc-zero-init.m @@ -0,0 +1,46 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -fobjc-arc %s + +#if __has_feature(objc_arc) +// expected-no-diagnostics +#endif + +@interface SomeClass +@end + +void simpleStrongPointerValue() { + SomeClass *x; + if (x) {} +#if !__has_feature(objc_arc) +// expected-warning@-2{{Branch condition evaluates to a garbage value}} +#endif +} + +void simpleArray() { + SomeClass *vlaArray[5]; + + if (vlaArray[0]) {} +#if !__has_feature(objc_arc) +// expected-warning@-2{{Branch condition evaluates to a garbage value}} +#endif +} + +void variableLengthArray() { + int count = 1; + SomeClass * vlaArray[count]; + + if (vlaArray[0]) {} +#if !__has_feature(objc_arc) + // expected-warning@-2{{Branch condition evaluates to a garbage value}} +#endif +} + +void variableLengthArrayWithExplicitStrongAttribute() { + int count = 1; + __attribute__((objc_ownership(strong))) SomeClass * vlaArray[count]; + + if (vlaArray[0]) {} +#if !__has_feature(objc_arc) + // expected-warning@-2{{Branch condition evaluates to a garbage value}} +#endif +} |