Teach SimpleSValBuilder that (in the absence of more information) stack memory doesn't alias symbolic memory. This is a heuristic/hack, but works well in practice. Fixes <rdar://problem/10978247>.

llvm-svn: 152065
This commit is contained in:
Ted Kremenek 2012-03-05 23:06:19 +00:00
parent bb6e7edd32
commit 9d96f843b8
3 changed files with 51 additions and 1 deletions

View File

@ -714,6 +714,24 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
// The two regions are from the same base region. See if they're both a
// type of region we know how to compare.
const MemSpaceRegion *LeftMS = LeftBase->getMemorySpace();
const MemSpaceRegion *RightMS = RightBase->getMemorySpace();
// Heuristic: assume that no symbolic region (whose memory space is
// unknown) is on the stack.
// FIXME: we should be able to be more precise once we can do better
// aliasing constraints for symbolic regions, but this is a reasonable,
// albeit unsound, assumption that holds most of the time.
if (isa<StackSpaceRegion>(LeftMS) ^ isa<StackSpaceRegion>(RightMS)) {
switch (op) {
default:
break;
case BO_EQ:
return makeTruthVal(false, resultTy);
case BO_NE:
return makeTruthVal(true, resultTy);
}
}
// FIXME: If/when there is a getAsRawOffset() for FieldRegions, this
// ElementRegion path and the FieldRegion path below should be unified.

View File

@ -728,6 +728,38 @@ int my_main_warn(FILE *f) {
return 0;// expected-warning {{leak}}
}
// <rdar://problem/10978247>.
// some people use stack allocated memory as an optimization to avoid
// a heap allocation for small work sizes. This tests the analyzer's
// understanding that the malloc'ed memory is not the same as stackBuffer.
void radar10978247(int myValueSize) {
char stackBuffer[128];
char *buffer;
if (myValueSize <= sizeof(stackBuffer))
buffer = stackBuffer;
else
buffer = malloc(myValueSize);
// do stuff with the buffer
if (buffer != stackBuffer)
free(buffer);
}
void radar10978247_positive(int myValueSize) {
char stackBuffer[128];
char *buffer;
if (myValueSize <= sizeof(stackBuffer))
buffer = stackBuffer;
else
buffer = malloc(myValueSize);
// do stuff with the buffer
if (buffer == stackBuffer) // expected-warning {{leak}}
return;
}
// ----------------------------------------------------------------------------
// Below are the known false positives.

View File

@ -269,7 +269,7 @@ void symbolic_region(int *p) {
int a;
if (&a == p)
WARN; // expected-warning{{}}
WARN; // no-warning
if (&a != p)
WARN; // expected-warning{{}}
if (&a > p)