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) {
|
||||
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,
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue