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:
parent
bb6e7edd32
commit
9d96f843b8
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue