[analyzer] do not warn about returning stack-allocated memory when it comes from an ancestor stack frame.

llvm-svn: 151964
This commit is contained in:
Ted Kremenek 2012-03-03 01:22:03 +00:00
parent 906ccc167c
commit 868dbda367
2 changed files with 39 additions and 12 deletions

View File

@ -113,7 +113,7 @@ void StackAddrEscapeChecker::EmitStackError(CheckerContext &C, const MemRegion *
}
void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS,
CheckerContext &C) const {
CheckerContext &C) const {
const Expr *RetE = RS->getRetValue();
if (!RetE)
@ -122,18 +122,26 @@ void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS,
SVal V = C.getState()->getSVal(RetE, C.getLocationContext());
const MemRegion *R = V.getAsRegion();
if (!R || !R->hasStackStorage())
return;
if (R->hasStackStorage()) {
// Automatic reference counting automatically copies blocks.
if (C.getASTContext().getLangOptions().ObjCAutoRefCount &&
isa<BlockDataRegion>(R))
return;
EmitStackError(C, R, RetE);
if (!R)
return;
}
const StackSpaceRegion *SS =
dyn_cast_or_null<StackSpaceRegion>(R->getMemorySpace());
if (!SS)
return;
// Return stack memory in an ancestor stack frame is fine.
const StackFrameContext *SFC = SS->getStackFrame();
if (SFC != C.getLocationContext()->getCurrentStackFrame())
return;
// Automatic reference counting automatically copies blocks.
if (C.getASTContext().getLangOptions().ObjCAutoRefCount &&
isa<BlockDataRegion>(R))
return;
EmitStackError(C, R, RetE);
}
void StackAddrEscapeChecker::checkEndPath(CheckerContext &Ctx) const {

View File

@ -58,3 +58,22 @@ void test_factorial_2() {
*p = 0xDEADBEEF; // no-warning
}
}
// Test that returning stack memory from a parent stack frame does
// not trigger a warning.
static char *return_buf(char *buf) {
return buf + 10;
}
void test_return_stack_memory_ok() {
char stack_buf[100];
char *pos = return_buf(stack_buf);
(void) pos;
}
char *test_return_stack_memory_bad() {
char stack_buf[100];
char *x = stack_buf;
return x; // expected-warning {{stack memory associated}}
}