]> granicus.if.org Git - clang/commitdiff
[analyzer] Invalidation checker: move the "missing implementation" check
authorAnna Zaks <ganna@apple.com>
Sat, 9 Feb 2013 01:09:27 +0000 (01:09 +0000)
committerAnna Zaks <ganna@apple.com>
Sat, 9 Feb 2013 01:09:27 +0000 (01:09 +0000)
The missing definition check should be in the same category as the
missing ivar validation - in this case, the intent is to invalidate in
the given class, as described in the declaration, but the implementation
does not perform the invalidation. Whereas the MissingInvalidationMethod
checker checks the cases where the method intention is not to
invalidate. The second checker has potential to have a much higher false
positive rate.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174787 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
test/Analysis/objc_invalidation.m

index 6262cb8ef9ddea3e16708711a71097d5b0c1defc..0389cc551b353aeab1f82ad1920b0013328a322b 100644 (file)
@@ -51,8 +51,7 @@ struct ChecksFilter {
   DefaultBool check_InstanceVariableInvalidation;
 };
 
-class IvarInvalidationCheckerImpl :
-  public Checker<check::ASTDecl<ObjCImplementationDecl> > {
+class IvarInvalidationCheckerImpl {
 
   typedef llvm::SmallSetVector<const ObjCMethodDecl*, 2> MethodSet;
   typedef llvm::DenseMap<const ObjCMethodDecl*,
@@ -471,12 +470,20 @@ visit(const ObjCImplementationDecl *ImplD) const {
   containsInvalidationMethod(InterfaceD, Info, /*LookForPartial*/ false);
 
   // Report an error in case none of the invalidation methods are declared.
-  if (!Info.needsInvalidation() && Filter.check_MissingInvalidationMethod) {
-    reportNoInvalidationMethod(FirstIvarDecl, IvarToPopertyMap, InterfaceD,
-                               /*MissingDeclaration*/ true);
+  if (!Info.needsInvalidation()) {
+    if (Filter.check_MissingInvalidationMethod)
+      reportNoInvalidationMethod(FirstIvarDecl, IvarToPopertyMap, InterfaceD,
+                                 /*MissingDeclaration*/ true);
+    // If there are no invalidation methods, there is no ivar validation work
+    // to be done.
     return;
   }
 
+  // Only check if Ivars are invalidated when InstanceVariableInvalidation
+  // has been requested.
+  if (!Filter.check_InstanceVariableInvalidation)
+    return;
+
   // Check that all ivars are invalidated by the invalidation methods.
   bool AtImplementationContainsAtLeastOneInvalidationMethod = false;
   for (MethodSet::iterator I = Info.InvalidationMethods.begin(),
@@ -489,11 +496,6 @@ visit(const ObjCImplementationDecl *ImplD) const {
     if (D && D->hasBody()) {
       AtImplementationContainsAtLeastOneInvalidationMethod = true;
 
-      // Only check if Ivars are invalidated when InstanceVariableInvalidation
-      // has been requested.
-      if (!Filter.check_InstanceVariableInvalidation)
-        break;
-
       // Get a copy of ivars needing invalidation.
       IvarSet IvarsI = Ivars;
 
@@ -517,8 +519,7 @@ visit(const ObjCImplementationDecl *ImplD) const {
   }
 
   // Report an error in case none of the invalidation methods are implemented.
-  if (!AtImplementationContainsAtLeastOneInvalidationMethod &&
-      Filter.check_MissingInvalidationMethod)
+  if (!AtImplementationContainsAtLeastOneInvalidationMethod)
     reportNoInvalidationMethod(FirstIvarDecl, IvarToPopertyMap, InterfaceD,
                                /*MissingDeclaration*/ false);
 }
index 1b29d36ef4bd0a688ade54e931b8fab8479fe991..a6f5ec3f84c70b4e296cef42b9c72c33e263f324 100644 (file)
@@ -250,7 +250,7 @@ extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1,
 
 @interface MissingInvalidationMethod : Foo <FooBar_Protocol>
 @property (assign) MissingInvalidationMethod *foobar15_warn;
-#if RUN_MISSING_INVALIDATION_METHOD
+#if RUN_IVAR_INVALIDATION
 // expected-warning@-2 {{Property foobar15_warn needs to be invalidated; no invalidation method is defined in the @implementation for MissingInvalidationMethod}}
 #endif
 @end
@@ -259,7 +259,7 @@ extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1,
 
 @interface MissingInvalidationMethod2 : Foo <FooBar_Protocol> {
   Foo *Ivar1;
-#if RUN_MISSING_INVALIDATION_METHOD
+#if RUN_IVAR_INVALIDATION
 // expected-warning@-2 {{Instance variable Ivar1 needs to be invalidated; no invalidation method is defined in the @implementation for MissingInvalidationMethod2}}
 #endif
 }