]> granicus.if.org Git - clang/commitdiff
[analyzer] Add an annotation to allow suppression of direct ivar
authorAnna Zaks <ganna@apple.com>
Wed, 16 Jan 2013 01:36:00 +0000 (01:36 +0000)
committerAnna Zaks <ganna@apple.com>
Wed, 16 Jan 2013 01:36:00 +0000 (01:36 +0000)
assignment

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

lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
test/Analysis/objc/direct-ivar-assignment-in-annotated-functions.m

index 378c1753385629fa0434e633bd266108d104024c..2cb511cbeaefeb3fb783b7d0129c254deb105f80 100644 (file)
@@ -155,6 +155,18 @@ void DirectIvarAssignment::checkASTDecl(const ObjCImplementationDecl *D,
   }
 }
 
+static bool isAnnotatedToAllowDirectAssignment(const ObjCPropertyDecl *D) {
+  for (specific_attr_iterator<AnnotateAttr>
+       AI = D->specific_attr_begin<AnnotateAttr>(),
+       AE = D->specific_attr_end<AnnotateAttr>(); AI != AE; ++AI) {
+    const AnnotateAttr *Ann = *AI;
+    if (Ann->getAnnotation() ==
+        "objc_allow_direct_instance_variable_assignment")
+      return true;
+  }
+  return false;
+}
+
 void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator(
                                                     const BinaryOperator *BO) {
   if (!BO->isAssignmentOp())
@@ -168,8 +180,14 @@ void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator(
 
   if (const ObjCIvarDecl *D = IvarRef->getDecl()) {
     IvarToPropertyMapTy::const_iterator I = IvarToPropMap.find(D);
+
     if (I != IvarToPropMap.end()) {
       const ObjCPropertyDecl *PD = I->second;
+      // Skip warnings on Ivars that correspond to properties, annotated with
+      // objc_allow_direct_instance_variable_assignment. This annotation serves
+      // as a false positive suppression mechanism for the checker.
+      if (isAnnotatedToAllowDirectAssignment(PD))
+        return;
 
       ObjCMethodDecl *GetterMethod =
           InterfD->getInstanceMethod(PD->getGetterName());
index cd425f3be0c42037c41d342d2c2a84412235495b..300f9775bfb60b4786e2bcba3bc45c2d7894aa0e 100644 (file)
@@ -13,14 +13,14 @@ typedef signed char BOOL;
 @interface MyClass;
 @end
 
-@interface AnnotatedClass :NSObject {
+@interface AnnotatedClass : NSObject {
 }
   - (void) someMethod: (MyClass*)In __attribute__((annotate("objc_no_direct_instance_variable_assignment")));
   - (void) someMethodNotAnnaotated: (MyClass*)In;
 @end
 
 
-@interface TestProperty :AnnotatedClass {
+@interface TestProperty : AnnotatedClass {
   MyClass *_Z;
   id _nonSynth;
 }
@@ -33,6 +33,9 @@ typedef signed char BOOL;
 
   @property (assign, nonatomic) MyClass* Z; // non synthesized ivar, implemented setter
   @property (readonly) id nonSynth;  // non synthesized, explicitly implemented to return ivar with expected name
+
+  @property (assign) MyClass* NotX __attribute__((annotate("objc_allow_direct_instance_variable_assignment")));  // warnings should be suppressed
+
   @end
 
 @implementation TestProperty
@@ -44,6 +47,7 @@ typedef signed char BOOL;
     _Y = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
     _Z = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
     _nonSynth = 0; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
+    _NotX = 0; // no-warning
   }
   - (void) someMethodNotAnnaotated: (MyClass*)In {
     (__A) = In;