RetainCountChecker: don't adjust the retain count when analyzing a ReturnStmt unless we are in the top-level call frame. We can do more later, but this makes the checker self-consistent (and fixes a crash).

llvm-svn: 151426
This commit is contained in:
Ted Kremenek 2012-02-25 02:09:09 +00:00
parent d5862ce317
commit ef31f376bb
2 changed files with 29 additions and 0 deletions

View File

@ -3069,8 +3069,23 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
// Handle return statements.
//===----------------------------------------------------------------------===//
// Return true if the current LocationContext has no caller context.
static bool inTopFrame(CheckerContext &C) {
const LocationContext *LC = C.getLocationContext();
return LC->getParent() == 0;
}
void RetainCountChecker::checkPreStmt(const ReturnStmt *S,
CheckerContext &C) const {
// Only adjust the reference count if this is the top-level call frame,
// and not the result of inlining. In the future, we should do
// better checking even for inlined calls, and see if they match
// with their expected semantics (e.g., the method should return a retained
// object, etc.).
if (!inTopFrame(C))
return;
const Expr *RetE = S->getRetValue();
if (!RetE)
return;

View File

@ -281,3 +281,17 @@ void test_neg() {
bar(s);
}
//===----------------------------------------------------------------------===//
// Test returning retained and not-retained values.
//===----------------------------------------------------------------------===//
id test_return_retained() {
return [[NSString alloc] init]; // expected-warning {{leak}}
}
void test_test_return_retained() {
id x = test_return_retained();
[x retain];
[x release];
}