From d98d22b9af01aa68f6b9fe73b2ce54b8463b6731 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 25 Feb 2010 03:26:55 +0000 Subject: [PATCH] Enhance the unused ivar checker to not consider an ivar to be accidentally unused when it is explicitly marked as unused via __attribute__((unused)). llvm-svn: 97104 --- clang/lib/Checker/CMakeLists.txt | 2 +- ...edIVars.cpp => ObjCUnusedIVarsChecker.cpp} | 29 +++++++++---------- clang/test/Analysis/unused-ivars.m | 15 ++++++++++ 3 files changed, 30 insertions(+), 16 deletions(-) rename clang/lib/Checker/{CheckObjCUnusedIVars.cpp => ObjCUnusedIVarsChecker.cpp} (92%) diff --git a/clang/lib/Checker/CMakeLists.txt b/clang/lib/Checker/CMakeLists.txt index 0e95b08d8720..fb771a5f04dd 100644 --- a/clang/lib/Checker/CMakeLists.txt +++ b/clang/lib/Checker/CMakeLists.txt @@ -18,7 +18,6 @@ add_clang_library(clangChecker CheckDeadStores.cpp CheckObjCDealloc.cpp CheckObjCInstMethSignature.cpp - CheckObjCUnusedIVars.cpp CheckSecuritySyntaxOnly.cpp CheckSizeofPointer.cpp Checker.cpp @@ -42,6 +41,7 @@ add_clang_library(clangChecker NSErrorChecker.cpp NoReturnFunctionChecker.cpp OSAtomicChecker.cpp + ObjCUnusedIVarsChecker.cpp PathDiagnostic.cpp PointerArithChecker.cpp PointerSubChecker.cpp diff --git a/clang/lib/Checker/CheckObjCUnusedIVars.cpp b/clang/lib/Checker/ObjCUnusedIVarsChecker.cpp similarity index 92% rename from clang/lib/Checker/CheckObjCUnusedIVars.cpp rename to clang/lib/Checker/ObjCUnusedIVarsChecker.cpp index f2cf58191632..04d897aec894 100644 --- a/clang/lib/Checker/CheckObjCUnusedIVars.cpp +++ b/clang/lib/Checker/ObjCUnusedIVarsChecker.cpp @@ -1,4 +1,4 @@ -//==- CheckObjCUnusedIVars.cpp - Check for unused ivars ----------*- C++ -*-==// +//==- ObjCUnusedIVarsChecker.cpp - Check for unused ivars --------*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -68,14 +68,14 @@ static void Scan(IvarUsageMap& M, const ObjCContainerDecl* D) { for (ObjCContainerDecl::instmeth_iterator I = D->instmeth_begin(), E = D->instmeth_end(); I!=E; ++I) Scan(M, (*I)->getBody()); - - if (const ObjCImplementationDecl *ID = dyn_cast(D)) { + + if (const ObjCImplementationDecl *ID = dyn_cast(D)) { // Scan for @synthesized property methods that act as setters/getters // to an ivar. for (ObjCImplementationDecl::propimpl_iterator I = ID->propimpl_begin(), E = ID->propimpl_end(); I!=E; ++I) Scan(M, *I); - + // Scan the associated categories as well. for (const ObjCCategoryDecl *CD = ID->getClassInterface()->getCategoryList(); CD ; @@ -92,7 +92,7 @@ static void Scan(IvarUsageMap &M, const DeclContext *C, const FileID FID, I!=E; ++I) if (const FunctionDecl *FD = dyn_cast(*I)) { SourceLocation L = FD->getLocStart(); - if (SM.getFileID(L) == FID) + if (SM.getFileID(L) == FID) Scan(M, FD->getBody()); } } @@ -109,12 +109,12 @@ void clang::CheckObjCUnusedIvar(const ObjCImplementationDecl *D, const ObjCIvarDecl* ID = *I; - // Ignore ivars that aren't private. - if (ID->getAccessControl() != ObjCIvarDecl::Private) - continue; - - // Skip IB Outlets. - if (ID->getAttr()) + // Ignore ivars that... + // (a) aren't private + // (b) explicitly marked unused + // (c) are iboutlets + if (ID->getAccessControl() != ObjCIvarDecl::Private || + ID->getAttr() || ID->getAttr()) continue; M[ID] = Unused; @@ -122,11 +122,10 @@ 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) @@ -134,10 +133,10 @@ void clang::CheckObjCUnusedIvar(const ObjCImplementationDecl *D, 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 diff --git a/clang/test/Analysis/unused-ivars.m b/clang/test/Analysis/unused-ivars.m index 600f0e28e036..14c43a86c408 100644 --- a/clang/test/Analysis/unused-ivars.m +++ b/clang/test/Analysis/unused-ivars.m @@ -81,3 +81,18 @@ int radar_7254495(RDar7254495 *a) { return a->x; } @end + +//===----------------------------------------------------------------------===// +// - consult attribute((unused)) to silence warnings +// about unused instance variables +//===----------------------------------------------------------------------===// + +@interface RDar7353683 { +@private + id x __attribute__((unused)); +} +@end + +@implementation RDar7353683 +@end +