Unused ivar checker: ivars referenced by lexically nested functions should not be flagged as unused. Fixes <rdar://problem/7254495>.

llvm-svn: 89448
This commit is contained in:
Ted Kremenek 2009-11-20 04:31:57 +00:00
parent 1aec3c0427
commit c1f161c012
2 changed files with 48 additions and 1 deletions

View File

@ -85,6 +85,17 @@ static void Scan(IvarUsageMap& M, const ObjCContainerDecl* D) {
}
}
static void Scan(IvarUsageMap &M, const DeclContext *C, const FileID FID,
SourceManager &SM) {
for (DeclContext::decl_iterator I=C->decls_begin(), E=C->decls_end();
I!=E; ++I)
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
SourceLocation L = FD->getLocStart();
if (SM.getFileID(L) == FID)
Scan(M, FD->getBody());
}
}
void clang::CheckObjCUnusedIvar(const ObjCImplementationDecl *D,
BugReporter &BR) {
@ -110,10 +121,30 @@ void clang::CheckObjCUnusedIvar(const ObjCImplementationDecl *D,
if (M.empty())
return;
// Now scan the implementation declaration.
Scan(M, D);
// Any potentially unused ivars?
bool hasUnused = false;
for (IvarUsageMap::iterator I = M.begin(), E = M.end(); I!=E; ++I)
if (I->second == Unused) {
hasUnused = true;
break;
}
if (!hasUnused)
return;
// We found some potentially unused ivars. Scan the entire translation unit
// for functions inside the @implementation that reference these ivars.
// FIXME: In the future hopefully we can just use the lexical DeclContext
// to go from the ObjCImplementationDecl to the lexically "nested"
// C functions.
SourceManager &SM = BR.getSourceManager();
Scan(M, D->getDeclContext(), SM.getFileID(D->getLocation()), SM);
// Find ivars that are unused.
for (IvarUsageMap::iterator I = M.begin(), E = M.end(); I!=E; ++I)
if (I->second == Unused) {

View File

@ -65,3 +65,19 @@
}
@end
//===----------------------------------------------------------------------===//
// <rdar://problem/7254495> - ivars referenced by lexically nested functions
// should not be flagged as unused
//===----------------------------------------------------------------------===//
@interface RDar7254495 {
@private
int x; // no-warning
}
@end
@implementation RDar7254495
int radar_7254495(RDar7254495 *a) {
return a->x;
}
@end