aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/RegionStore.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-01-31 02:57:06 +0000
committerJordan Rose <jordan_rose@apple.com>2013-01-31 02:57:06 +0000
commit0e450cbd94e5936fdecf42b810069e7becd3938d (patch)
treeddc63287fa422193a46c3ec759a8b027304bdd18 /lib/StaticAnalyzer/Core/RegionStore.cpp
parentf499b34d4911dda3b20ede1377ea29b83d3f149e (diff)
[analyzer] If a lazy binding is undefined, pretend that it's unknown instead.
This is a hack to work around the fact that we don't track extents for our default bindings: CGPoint p; p.x = 0.0; p.y = 0.0; rectParam.origin = p; use(rectParam.size); // warning: uninitialized value in rectParam.size.width In this case, the default binding for 'p' gets copied into 'rectParam', because the 'origin' field is at offset 0 within CGRect. From then on, rectParam's old default binding (in this case a symbol) is lost. This patch silences the warning by pretending that lazy bindings are never made from uninitialized memory, but not only is that not true, the original default binding is still getting overwritten (see FIXME test cases). The long-term solution is tracked in <rdar://problem/12701038> PR14765 and <rdar://problem/12875012> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174031 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp26
1 files changed, 24 insertions, 2 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index a37223a528..06218664f7 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -1384,9 +1384,31 @@ RegionStoreManager::getBindingForDerivedDefaultValue(RegionBindingsConstRef B,
SVal RegionStoreManager::getLazyBinding(const MemRegion *LazyBindingRegion,
RegionBindingsRef LazyBinding) {
+ SVal Result;
if (const ElementRegion *ER = dyn_cast<ElementRegion>(LazyBindingRegion))
- return getBindingForElement(LazyBinding, ER);
- return getBindingForField(LazyBinding, cast<FieldRegion>(LazyBindingRegion));
+ Result = getBindingForElement(LazyBinding, ER);
+ else
+ Result = getBindingForField(LazyBinding,
+ cast<FieldRegion>(LazyBindingRegion));
+
+ // This is a hack to deal with RegionStore's inability to distinguish a
+ // default value for /part/ of an aggregate from a default value for the
+ // /entire/ aggregate. The most common case of this is when struct Outer
+ // has as its first member a struct Inner, which is copied in from a stack
+ // variable. In this case, even if the Outer's default value is symbolic, 0,
+ // or unknown, it gets overridden by the Inner's default value of undefined.
+ //
+ // This is a general problem -- if the Inner is zero-initialized, the Outer
+ // will now look zero-initialized. The proper way to solve this is with a
+ // new version of RegionStore that tracks the extent of a binding as well
+ // as the offset.
+ //
+ // This hack only takes care of the undefined case because that can very
+ // quickly result in a warning.
+ if (Result.isUndef())
+ Result = UnknownVal();
+
+ return Result;
}
SVal