[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.

llvm-svn: 177905
This commit is contained in:
Anna Zaks 2013-03-25 20:43:24 +00:00
parent 2d752fc2f9
commit f60f2fb142
2 changed files with 44 additions and 4 deletions

View File

@ -833,14 +833,22 @@ RegionStoreManager::removeSubRegionBindings(RegionBindingsConstRef B,
const SubRegion *Top) { const SubRegion *Top) {
BindingKey TopKey = BindingKey::Make(Top, BindingKey::Default); BindingKey TopKey = BindingKey::Make(Top, BindingKey::Default);
const MemRegion *ClusterHead = TopKey.getBaseRegion(); const MemRegion *ClusterHead = TopKey.getBaseRegion();
const ClusterBindings *Cluster = B.lookup(ClusterHead);
if (Top == ClusterHead) { if (Top == ClusterHead) {
// We can remove an entire cluster's bindings all in one go. // We can remove an entire cluster's bindings all in one go.
return B.remove(Top); 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; return B;
}
SmallVector<BindingPair, 32> Bindings; SmallVector<BindingPair, 32> Bindings;
collectSubRegionBindings(Bindings, svalBuilder, *Cluster, Top, TopKey, collectSubRegionBindings(Bindings, svalBuilder, *Cluster, Top, TopKey,

View File

@ -1,5 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,debug.ExprInspection -verify %s
// expected-no-diagnostics
int printf(const char *restrict,...); int printf(const char *restrict,...);
@ -22,3 +21,36 @@ int compoundLiteralTest2() {
} }
return 0; 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}}
}
}