]> granicus.if.org Git - clang/commitdiff
Fix: <rdar://problem/7075531> static analyzer wrongly detects unused ivars used in...
authorTed Kremenek <kremenek@apple.com>
Fri, 7 Aug 2009 21:13:23 +0000 (21:13 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 7 Aug 2009 21:13:23 +0000 (21:13 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78409 91177308-0d34-0410-b5e6-96231b3b80d8

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

index dbc90d65c30a47eb10bf1607600085ee60832178..3a69e00499d400c1b62ba24ad207a537c1f6164f 100644 (file)
@@ -30,14 +30,20 @@ static void Scan(IvarUsageMap& M, const Stmt* S) {
   if (!S)
     return;
   
-  if (const ObjCIvarRefExprEx = dyn_cast<ObjCIvarRefExpr>(S)) {
-    const ObjCIvarDeclD = Ex->getDecl();
+  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);
 }
index 632b395c3e081d267c2b247f9145e6260e86fe76..aacd44e7e6777985450358100a83e9274563ae36 100644 (file)
@@ -1,10 +1,45 @@
-// RUN: clang-cc -analyze -warn-objc-unused-ivars %s -verify
+// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -warn-objc-unused-ivars %s -verify
 
-@interface A
-{
-  @private int x; // expected-warning {{Instance variable 'x' in class 'A' is never used}}
+//===--- BEGIN: Delta-debugging reduced headers. --------------------------===//
+
+@protocol NSObject
+- (id)retain;
+- (oneway void)release;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)alloc;
+@end
+
+//===--- END: Delta-debugging reduced headers. ----------------------------===//
+
+// This test case tests the basic functionality of the unused ivar test.
+@interface TestA {
+@private
+  int x; // expected-warning {{Instance variable 'x' in class 'TestA' is never used}}
 }
 @end
+@implementation TestA @end
 
-@implementation A @end
+// This test case tests whether the unused ivar check handles blocks that
+// reference an instance variable. (<rdar://problem/7075531>)
+@interface TestB : NSObject {
+@private
+  id _ivar; // no-warning
+}
+@property (readwrite,retain) id ivar;
+@end
+
+@implementation TestB
+- (id)ivar {
+  __attribute__((__blocks__(byref))) id value = ((void*)0);
+  void (^b)() = ^{ value = _ivar; };
+  b();
+  return value;
+}
 
+- (void)setIvar:(id)newValue {
+  void (^b)() = ^{ [_ivar release]; _ivar = [newValue retain]; };
+  b();
+}
+@end