[cfe-commits] r97104 - in /cfe/trunk: lib/Checker/CMakeLists.txt lib/Checker/CheckObjCUnusedIVars.cpp lib/Checker/ObjCUnusedIVarsChecker.cpp test/Analysis/unused-ivars.m

Ted Kremenek kremenek at apple.com
Wed Feb 24 19:26:56 PST 2010


Author: kremenek
Date: Wed Feb 24 21:26:55 2010
New Revision: 97104

URL: http://llvm.org/viewvc/llvm-project?rev=97104&view=rev
Log:
Enhance the unused ivar checker to not consider an ivar to be accidentally unused
when it is explicitly marked as unused via __attribute__((unused)).

Added:
    cfe/trunk/lib/Checker/ObjCUnusedIVarsChecker.cpp
      - copied, changed from r97103, cfe/trunk/lib/Checker/CheckObjCUnusedIVars.cpp
Removed:
    cfe/trunk/lib/Checker/CheckObjCUnusedIVars.cpp
Modified:
    cfe/trunk/lib/Checker/CMakeLists.txt
    cfe/trunk/test/Analysis/unused-ivars.m

Modified: cfe/trunk/lib/Checker/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/CMakeLists.txt?rev=97104&r1=97103&r2=97104&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/CMakeLists.txt (original)
+++ cfe/trunk/lib/Checker/CMakeLists.txt Wed Feb 24 21:26:55 2010
@@ -18,7 +18,6 @@
   CheckDeadStores.cpp
   CheckObjCDealloc.cpp
   CheckObjCInstMethSignature.cpp
-  CheckObjCUnusedIVars.cpp
   CheckSecuritySyntaxOnly.cpp
   CheckSizeofPointer.cpp
   Checker.cpp
@@ -42,6 +41,7 @@
   NSErrorChecker.cpp
   NoReturnFunctionChecker.cpp
   OSAtomicChecker.cpp
+  ObjCUnusedIVarsChecker.cpp
   PathDiagnostic.cpp
   PointerArithChecker.cpp
   PointerSubChecker.cpp

Removed: cfe/trunk/lib/Checker/CheckObjCUnusedIVars.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/CheckObjCUnusedIVars.cpp?rev=97103&view=auto
==============================================================================
--- cfe/trunk/lib/Checker/CheckObjCUnusedIVars.cpp (original)
+++ cfe/trunk/lib/Checker/CheckObjCUnusedIVars.cpp (removed)
@@ -1,162 +0,0 @@
-//==- CheckObjCUnusedIVars.cpp - Check for unused ivars ----------*- C++ -*-==//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines a CheckObjCUnusedIvars, a checker that
-//  analyzes an Objective-C class's interface/implementation to determine if it
-//  has any ivars that are never accessed.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Checker/Checkers/LocalCheckers.h"
-#include "clang/Checker/BugReporter/PathDiagnostic.h"
-#include "clang/Checker/BugReporter/BugReporter.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceManager.h"
-
-using namespace clang;
-
-enum IVarState { Unused, Used };
-typedef llvm::DenseMap<const ObjCIvarDecl*,IVarState> IvarUsageMap;
-
-static void Scan(IvarUsageMap& M, const Stmt* S) {
-  if (!S)
-    return;
-
-  if (const ObjCIvarRefExpr *Ex = dyn_cast<ObjCIvarRefExpr>(S)) {
-    const ObjCIvarDecl *D = Ex->getDecl();
-    IvarUsageMap::iterator I = M.find(D);
-    if (I != M.end())
-      I->second = Used;
-    return;
-  }
-
-  // Blocks can reference an instance variable of a class.
-  if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
-    Scan(M, BE->getBody());
-    return;
-  }
-
-  for (Stmt::const_child_iterator I=S->child_begin(),E=S->child_end(); I!=E;++I)
-    Scan(M, *I);
-}
-
-static void Scan(IvarUsageMap& M, const ObjCPropertyImplDecl* D) {
-  if (!D)
-    return;
-
-  const ObjCIvarDecl* ID = D->getPropertyIvarDecl();
-
-  if (!ID)
-    return;
-
-  IvarUsageMap::iterator I = M.find(ID);
-  if (I != M.end())
-    I->second = Used;
-}
-
-static void Scan(IvarUsageMap& M, const ObjCContainerDecl* D) {
-  // Scan the methods for accesses.
-  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<ObjCImplementationDecl>(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 ;
-          CD = CD->getNextClassCategory()) {
-      if (const ObjCCategoryImplDecl *CID = CD->getImplementation())
-        Scan(M, CID);
-    }
-  }
-}
-
-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) {
-
-  const ObjCInterfaceDecl* ID = D->getClassInterface();
-  IvarUsageMap M;
-
-  // Iterate over the ivars.
-  for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(),
-        E=ID->ivar_end(); I!=E; ++I) {
-
-    const ObjCIvarDecl* ID = *I;
-
-    // Ignore ivars that aren't private.
-    if (ID->getAccessControl() != ObjCIvarDecl::Private)
-      continue;
-
-    // Skip IB Outlets.
-    if (ID->getAttr<IBOutletAttr>())
-      continue;
-
-    M[ID] = Unused;
-  }
-
-  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) {
-      std::string sbuf;
-      llvm::raw_string_ostream os(sbuf);
-      os << "Instance variable '" << I->first->getNameAsString()
-         << "' in class '" << ID->getNameAsString()
-         << "' is never used by the methods in its @implementation "
-            "(although it may be used by category methods).";
-
-      BR.EmitBasicReport("Unused instance variable", "Optimization",
-                         os.str(), I->first->getLocation());
-    }
-}

Copied: cfe/trunk/lib/Checker/ObjCUnusedIVarsChecker.cpp (from r97103, cfe/trunk/lib/Checker/CheckObjCUnusedIVars.cpp)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/ObjCUnusedIVarsChecker.cpp?p2=cfe/trunk/lib/Checker/ObjCUnusedIVarsChecker.cpp&p1=cfe/trunk/lib/Checker/CheckObjCUnusedIVars.cpp&r1=97103&r2=97104&rev=97104&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/CheckObjCUnusedIVars.cpp (original)
+++ cfe/trunk/lib/Checker/ObjCUnusedIVarsChecker.cpp Wed Feb 24 21:26:55 2010
@@ -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 @@
   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<ObjCImplementationDecl>(D)) {    
+
+  if (const ObjCImplementationDecl *ID = dyn_cast<ObjCImplementationDecl>(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 @@
        I!=E; ++I)
     if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
       SourceLocation L = FD->getLocStart();
-      if (SM.getFileID(L) == FID)      
+      if (SM.getFileID(L) == FID)
         Scan(M, FD->getBody());
     }
 }
@@ -109,12 +109,12 @@
 
     const ObjCIvarDecl* ID = *I;
 
-    // Ignore ivars that aren't private.
-    if (ID->getAccessControl() != ObjCIvarDecl::Private)
-      continue;
-
-    // Skip IB Outlets.
-    if (ID->getAttr<IBOutletAttr>())
+    // Ignore ivars that...
+    // (a) aren't private
+    // (b) explicitly marked unused
+    // (c) are iboutlets
+    if (ID->getAccessControl() != ObjCIvarDecl::Private ||
+        ID->getAttr<UnusedAttr>() || ID->getAttr<IBOutletAttr>())
       continue;
 
     M[ID] = Unused;
@@ -122,11 +122,10 @@
 
   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 @@
       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

Modified: cfe/trunk/test/Analysis/unused-ivars.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/unused-ivars.m?rev=97104&r1=97103&r2=97104&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/unused-ivars.m (original)
+++ cfe/trunk/test/Analysis/unused-ivars.m Wed Feb 24 21:26:55 2010
@@ -81,3 +81,18 @@
   return a->x;
 }
 @end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7353683> - consult attribute((unused)) to silence warnings
+// about unused instance variables
+//===----------------------------------------------------------------------===//
+
+ at interface RDar7353683 {
+ at private
+  id x __attribute__((unused));
+}
+ at end
+
+ at implementation RDar7353683
+ at end
+





More information about the cfe-commits mailing list