forked from OSchip/llvm-project
[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:
parent
906ccc167c
commit
868dbda367
|
@ -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 {
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue