diff options
author | Anna Zaks <ganna@apple.com> | 2013-03-25 20:43:24 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2013-03-25 20:43:24 +0000 |
commit | 5db8fac5f304d9973f724d5aeb4108367d36f781 (patch) | |
tree | c8d20f8ed7d3ac39556fddd37d8ea2ca079a1478 | |
parent | 4eb17e553c63f701c7f565e12bc6c5dff4d914d5 (diff) |
[analyzer] Set concrete offset bindings to UnknownVal when processing symbolic offset binding, even if no bindings are present.
This addresses an undefined value false positive from concreteOffsetBindingIsInvalidatedBySymbolicOffsetAssignment.
Fixes PR14877; radar://12991168.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177905 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/StaticAnalyzer/Core/RegionStore.cpp | 12 | ||||
-rw-r--r-- | test/Analysis/region-store.c | 36 |
2 files changed, 44 insertions, 4 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index 58d94304ba..ae2752d00a 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -833,14 +833,22 @@ RegionStoreManager::removeSubRegionBindings(RegionBindingsConstRef B, const SubRegion *Top) { BindingKey TopKey = BindingKey::Make(Top, BindingKey::Default); const MemRegion *ClusterHead = TopKey.getBaseRegion(); + const ClusterBindings *Cluster = B.lookup(ClusterHead); + if (Top == ClusterHead) { // We can remove an entire cluster's bindings all in one go. return B.remove(Top); } - const ClusterBindings *Cluster = B.lookup(ClusterHead); - if (!Cluster) + if (!Cluster) { + // If we're invalidating a region with a symbolic offset, we need to make + // sure we don't treat the base region as uninitialized anymore. + if (TopKey.hasSymbolicOffset()) { + const SubRegion *Concrete = TopKey.getConcreteOffsetRegion(); + return B.addBinding(Concrete, BindingKey::Default, UnknownVal()); + } return B; + } SmallVector<BindingPair, 32> Bindings; collectSubRegionBindings(Bindings, svalBuilder, *Cluster, Top, TopKey, diff --git a/test/Analysis/region-store.c b/test/Analysis/region-store.c index d620150085..70bda1117b 100644 --- a/test/Analysis/region-store.c +++ b/test/Analysis/region-store.c @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s -// expected-no-diagnostics +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,debug.ExprInspection -verify %s int printf(const char *restrict,...); @@ -22,3 +21,36 @@ int compoundLiteralTest2() { } return 0; } + +int concreteOffsetBindingIsInvalidatedBySymbolicOffsetAssignment(int length, + int i) { + int values[length]; + values[i] = 4; + return values[0]; // no-warning +} + +struct X{ + int mem; +}; +int initStruct(struct X *st); +int structOffsetBindingIsInvalidated(int length, int i){ + struct X l; + initStruct(&l); + return l.mem; // no-warning +} + +void clang_analyzer_eval(int); +void testConstraintOnRegionOffset(int *values, int length, int i){ + if (values[1] == 4) { + values[i] = 5; + clang_analyzer_eval(values[1] == 4);// expected-warning {{UNKNOWN}} + } +} + +int initArray(int *values); +void testConstraintOnRegionOffsetStack(int *values, int length, int i) { + if (values[0] == 4) { + initArray(values); + clang_analyzer_eval(values[0] == 4);// expected-warning {{UNKNOWN}} + } +} |