]> granicus.if.org Git - clang/commitdiff
Unused ivar checker: ivars referenced by lexically nested functions should not be...
authorTed Kremenek <kremenek@apple.com>
Fri, 20 Nov 2009 04:31:57 +0000 (04:31 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 20 Nov 2009 04:31:57 +0000 (04:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89448 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CheckObjCUnusedIVars.cpp
test/Analysis/unused-ivars.m

index 2d9b53163f6adf220a0dd19d2aeca9b48c43546a..3ee5cb12d95d00abcaa728e32fc2274ebd591374 100644 (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) {
index 754799b2dbd8a5719a01bcb37adbaf64de0d040e..bbbf6aec23dd488d2fca44b6451f935f7cf4ecf5 100644 (file)
 }
 @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