[analyzer] Re-implement IvarInvalidationChecker so that it verifies that
the validation occurred.

The original implementation was pessimistic - we assumed that ivars
which escape are invalidated. This version is optimistic, it assumes
that the ivars will always be explicitly invalidated: either set to nil
or sent an invalidation message.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164868 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/objc_invalidation.m b/test/Analysis/objc_invalidation.m
index ededae6..adcbbd6 100644
--- a/test/Analysis/objc_invalidation.m
+++ b/test/Analysis/objc_invalidation.m
@@ -10,7 +10,11 @@
 -(id)copy;
 - (Class)class;
 -(id)retain;
+-(id)description;
 @end
+@class NSString;
+
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
 
 @protocol Invalidation1 <NSObject> 
 - (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
@@ -22,6 +26,7 @@
 
 @protocol Invalidation3 <NSObject>
 - (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
+- (void) invalidate2 __attribute__((annotate("objc_instance_variable_invalidator")));
 @end
 
 @interface Invalidation2Class <Invalidation2>
@@ -31,7 +36,7 @@
 @end
 
 @interface SomeInvalidationImplementingObject: NSObject <Invalidation3, Invalidation2> {
-  SomeInvalidationImplementingObject *ObjA;
+  SomeInvalidationImplementingObject *ObjA; // invalidation in the parent
 }
 @end
 
@@ -39,21 +44,28 @@
 - (void)invalidate{
   ObjA = 0;
 }
+- (void)invalidate2 {
+  [self invalidate];
+}
 @end
 
 @interface SomeSubclassInvalidatableObject : SomeInvalidationImplementingObject {
-  SomeInvalidationImplementingObject *Obj1; 
-  SomeInvalidationImplementingObject *Obj2;
-  SomeInvalidationImplementingObject *Obj3;
-  SomeInvalidationImplementingObject *_Prop1;
-  SomeInvalidationImplementingObject *_Prop4;
-  SomeInvalidationImplementingObject *_propIvar;
-  Invalidation1Class *MultipleProtocols;
-  Invalidation2Class *MultInheritance; 
-  SomeInvalidationImplementingObject *_Prop5; // invalidate via getter method
+  SomeInvalidationImplementingObject *Ivar1; // regular ivar
+  SomeInvalidationImplementingObject *Ivar2; // regular ivar, sending invalidate message
+  SomeInvalidationImplementingObject *_Ivar3; // no property, call -description
+  SomeInvalidationImplementingObject *_Ivar4; // no property, provide as argument to NSLog()
+
+  SomeInvalidationImplementingObject *_Prop1; // partially implemented property, set to 0 with dot syntax
+  SomeInvalidationImplementingObject *_Prop2; // fully implemented prop, set to 0 with dot syntax
+  SomeInvalidationImplementingObject *_propIvar; // property with custom named ivar, set to 0 via setter
+  Invalidation1Class *MultipleProtocols; // regular ivar belonging to a different class
+  Invalidation2Class *MultInheritance; // regular ivar belonging to a different class
+  SomeInvalidationImplementingObject *_Prop3; // property, invalidate via sending a message to a getter method
+  SomeInvalidationImplementingObject *_Prop4; // property with @synthesize, invalidate via property
+  SomeInvalidationImplementingObject *_Prop5; // property with @synthesize, invalidate via getter method
   
-  // No warnings on these.
-  NSObject *NObj1;
+  // No warnings on these as they are not invalidatable.
+  NSObject *NIvar1;
   NSObject *NObj2;
   NSObject *_NProp1;
   NSObject *_NpropIvar;
@@ -63,10 +75,12 @@
 @property (nonatomic, assign) SomeInvalidationImplementingObject* Prop1;
 @property (assign) SomeInvalidationImplementingObject* Prop2;
 @property (assign) SomeInvalidationImplementingObject* Prop3;
-@property (assign) SomeInvalidationImplementingObject* Prop4;
-@property (assign) SomeInvalidationImplementingObject* Prop5;
-@property (assign) SomeInvalidationImplementingObject *SynthIvarProp;
+@property (assign) SomeInvalidationImplementingObject *Prop5;
+@property (assign) SomeInvalidationImplementingObject *Prop4;
 
+@property (assign) SomeInvalidationImplementingObject* Prop6; // automatically synthesized prop
+@property (assign) SomeInvalidationImplementingObject* Prop7; // automatically synthesized prop
+@property (assign) SomeInvalidationImplementingObject *SynthIvarProp;
 
 @property (assign) NSObject* NProp0;
 @property (nonatomic, assign) NSObject* NProp1;
@@ -81,18 +95,21 @@
 
 @implementation SomeSubclassInvalidatableObject
 
-@synthesize Prop2 = _propIvar;
-@synthesize Prop3;
+@synthesize Prop7 = _propIvar;
+@synthesize Prop3 = _Prop3;
+@synthesize Prop5 = _Prop5;
+@synthesize Prop4 = _Prop4;
+
 
 - (void) setProp1: (SomeInvalidationImplementingObject*) InObj {
   _Prop1 = InObj;
 }
 
-- (void) setProp4: (SomeInvalidationImplementingObject*) InObj {
-  _Prop4 = InObj;
+- (void) setProp2: (SomeInvalidationImplementingObject*) InObj {
+  _Prop2 = InObj;
 }
-- (SomeInvalidationImplementingObject*) Prop4 {
-  return _Prop4;
+- (SomeInvalidationImplementingObject*) Prop2 {
+  return _Prop2;
 }
 
 @synthesize NProp2 = _NpropIvar;
@@ -102,17 +119,24 @@
 }
 
 - (void) invalidate {
-   [Obj3 invalidate];
+   [Ivar2 invalidate];
    self.Prop0 = 0;
    self.Prop1 = 0;
    [self setProp2:0];
    [self setProp3:0];
-   self.Prop4 = 0;
-   [[self Prop5] invalidate];
+   [[self Prop5] invalidate2];
+   [self.Prop4 invalidate];
+   self.Prop6 = 0;
+   [[self Prop7] invalidate];
+
+   [_Ivar3 description]; 
+   NSLog(@"%@", _Ivar4);
    [super invalidate];
-}// expected-warning {{Instance variable Obj1 needs to be invalidated}}
- // expected-warning@-1 {{Instance variable Obj2 needs to be invalidated}}
+}
+// expected-warning@-1 {{Instance variable Ivar1 needs to be invalidated}}
  // expected-warning@-2 {{Instance variable MultipleProtocols needs to be invalidated}}
  // expected-warning@-3 {{Instance variable MultInheritance needs to be invalidated}}
  // expected-warning@-4 {{Property SynthIvarProp needs to be invalidated}}
+ // expected-warning@-5 {{Instance variable _Ivar3 needs to be invalidated}}
+ // expected-warning@-6 {{Instance variable _Ivar4 needs to be invalidated}}
 @end