forked from OSchip/llvm-project
[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:
parent
2d752fc2f9
commit
f60f2fb142
|
@ -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,
|
||||||
|
|
|
@ -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}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue