| // RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s | 
 | // RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s | 
 |  | 
 | @interface Test { | 
 | @public | 
 |   Test *ivar; | 
 |   __weak id weakIvar; | 
 | } | 
 | @property(weak) Test *weakProp; | 
 | @property(strong) Test *strongProp; | 
 |  | 
 | - (__weak id)implicitProp; | 
 |  | 
 | + (__weak id)weakProp; | 
 | @end | 
 |  | 
 | extern void use(id); | 
 | extern id get(); | 
 | extern bool condition(); | 
 | #define nil ((id)0) | 
 |  | 
 | void basicCorrectnessTest(Test *a) { | 
 |   use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function but may be unpredictably set to nil; assign to a strong variable to keep the object alive}} | 
 |   use(a.weakProp); // expected-note{{also accessed here}} | 
 |  | 
 |   use(a.strongProp); | 
 |   use(a.strongProp); // no-warning | 
 |  | 
 |   use(a.weakProp); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | void singleUse(Test *a) { | 
 |   use(a.weakProp); // no-warning | 
 |   use(a.strongProp); // no-warning | 
 | } | 
 |  | 
 | void assignsOnly(Test *a) { | 
 |   a.weakProp = get(); // no-warning | 
 |  | 
 |   id next = get(); | 
 |   if (next) | 
 |     a.weakProp = next; // no-warning | 
 |  | 
 |   a->weakIvar = get(); // no-warning | 
 |   next = get(); | 
 |   if (next) | 
 |     a->weakIvar = next; // no-warning | 
 |  | 
 |   extern __weak id x; | 
 |   x = get(); // no-warning | 
 |   next = get(); | 
 |   if (next) | 
 |     x = next; // no-warning | 
 | } | 
 |  | 
 | void assignThenRead(Test *a) { | 
 |   a.weakProp = get(); // expected-note{{also accessed here}} | 
 |   use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} | 
 | } | 
 |  | 
 | void twoVariables(Test *a, Test *b) { | 
 |   use(a.weakProp); // no-warning | 
 |   use(b.weakProp); // no-warning | 
 | } | 
 |  | 
 | void doubleLevelAccess(Test *a) { | 
 |   use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times in this function and may be unpredictably set to nil; assign to a strong variable to keep the object alive}} | 
 |   use(a.strongProp.weakProp); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | void doubleLevelAccessIvar(Test *a) { | 
 |   use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} | 
 |   use(a.strongProp.weakProp); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | void implicitProperties(Test *a) { | 
 |   use(a.implicitProp); // expected-warning{{weak implicit property 'implicitProp' is accessed multiple times}} | 
 |   use(a.implicitProp); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | void classProperties() { | 
 |   use(Test.weakProp); // expected-warning{{weak implicit property 'weakProp' is accessed multiple times}} | 
 |   use(Test.weakProp); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | void classPropertiesAreDifferent(Test *a) { | 
 |   use(Test.weakProp); // no-warning | 
 |   use(a.weakProp); // no-warning | 
 |   use(a.strongProp.weakProp); // no-warning | 
 | } | 
 |  | 
 | void ivars(Test *a) { | 
 |   use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}} | 
 |   use(a->weakIvar); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | void globals() { | 
 |   extern __weak id a; | 
 |   use(a); // expected-warning{{weak variable 'a' is accessed multiple times}} | 
 |   use(a); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | void messageGetter(Test *a) { | 
 |   use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}} | 
 |   use([a weakProp]); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | void messageSetter(Test *a) { | 
 |   [a setWeakProp:get()]; // no-warning | 
 |   [a setWeakProp:get()]; // no-warning | 
 | } | 
 |  | 
 | void messageSetterAndGetter(Test *a) { | 
 |   [a setWeakProp:get()]; // expected-note{{also accessed here}} | 
 |   use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}} | 
 | } | 
 |  | 
 | void mixDotAndMessageSend(Test *a, Test *b) { | 
 |   use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} | 
 |   use([a weakProp]); // expected-note{{also accessed here}} | 
 |  | 
 |   use([b weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}} | 
 |   use(b.weakProp); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 |  | 
 | void assignToStrongWrongInit(Test *a) { | 
 |   id val = a.weakProp; // expected-note{{also accessed here}} | 
 |   use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} | 
 | } | 
 |  | 
 | void assignToStrongWrong(Test *a) { | 
 |   id val; | 
 |   val = a.weakProp; // expected-note{{also accessed here}} | 
 |   use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} | 
 | } | 
 |  | 
 | void assignToIvarWrong(Test *a) { | 
 |   a->weakIvar = get(); // expected-note{{also accessed here}} | 
 |   use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}} | 
 | } | 
 |  | 
 | void assignToGlobalWrong() { | 
 |   extern __weak id a; | 
 |   a = get(); // expected-note{{also accessed here}} | 
 |   use(a); // expected-warning{{weak variable 'a' is accessed multiple times}} | 
 | } | 
 |  | 
 | void assignToStrongOK(Test *a) { | 
 |   if (condition()) { | 
 |     id val = a.weakProp; // no-warning | 
 |     (void)val; | 
 |   } else { | 
 |     id val; | 
 |     val = a.weakProp; // no-warning | 
 |     (void)val; | 
 |   } | 
 | } | 
 |  | 
 | void assignToStrongConditional(Test *a) { | 
 |   id val = (condition() ? a.weakProp : a.weakProp); // no-warning | 
 |   id val2 = a.implicitProp ?: a.implicitProp; // no-warning | 
 | } | 
 |  | 
 | void testBlock(Test *a) { | 
 |   use(a.weakProp); // no-warning | 
 |  | 
 |   use(^{ | 
 |     use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this block}} | 
 |     use(a.weakProp); // expected-note{{also accessed here}} | 
 |   }); | 
 | } | 
 |  | 
 | void assignToStrongWithCasts(Test *a) { | 
 |   if (condition()) { | 
 |     Test *val = (Test *)a.weakProp; // no-warning | 
 |     (void)val; | 
 |   } else { | 
 |     id val; | 
 |     val = (Test *)a.weakProp; // no-warning | 
 |     (void)val; | 
 |   } | 
 | } | 
 |  | 
 | void assignToStrongWithMessages(Test *a) { | 
 |   if (condition()) { | 
 |     id val = [a weakProp]; // no-warning | 
 |     (void)val; | 
 |   } else { | 
 |     id val; | 
 |     val = [a weakProp]; // no-warning | 
 |     (void)val; | 
 |   } | 
 | } | 
 |  | 
 |  | 
 | void assignAfterRead(Test *a) { | 
 |   // Special exception for a single read before any writes. | 
 |   if (!a.weakProp) // no-warning | 
 |     a.weakProp = get(); // no-warning | 
 | } | 
 |  | 
 | void readOnceWriteMany(Test *a) { | 
 |   if (!a.weakProp) { // no-warning | 
 |     a.weakProp = get(); // no-warning | 
 |     a.weakProp = get(); // no-warning | 
 |   } | 
 | } | 
 |  | 
 | void readOnceAfterWrite(Test *a) { | 
 |   a.weakProp = get(); // expected-note{{also accessed here}} | 
 |   if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} | 
 |     a.weakProp = get(); // expected-note{{also accessed here}} | 
 |   } | 
 | } | 
 |  | 
 | void readOnceWriteManyLoops(Test *a, Test *b, Test *c, Test *d, Test *e) { | 
 |   while (condition()) { | 
 |     if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} | 
 |       a.weakProp = get(); // expected-note{{also accessed here}} | 
 |       a.weakProp = get(); // expected-note{{also accessed here}} | 
 |     } | 
 |   } | 
 |  | 
 |   do { | 
 |     if (!b.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} | 
 |       b.weakProp = get(); // expected-note{{also accessed here}} | 
 |       b.weakProp = get(); // expected-note{{also accessed here}} | 
 |     } | 
 |   } while (condition()); | 
 |  | 
 |   for (id x = get(); x; x = get()) { | 
 |     if (!c.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} | 
 |       c.weakProp = get(); // expected-note{{also accessed here}} | 
 |       c.weakProp = get(); // expected-note{{also accessed here}} | 
 |     } | 
 |   } | 
 |  | 
 |   for (id x in get()) { | 
 |     if (!d.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} | 
 |       d.weakProp = get(); // expected-note{{also accessed here}} | 
 |       d.weakProp = get(); // expected-note{{also accessed here}} | 
 |     } | 
 |   } | 
 |  | 
 |   int array[] = { 1, 2, 3 }; | 
 |   for (int i : array) { | 
 |     if (!e.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} | 
 |       e.weakProp = get(); // expected-note{{also accessed here}} | 
 |       e.weakProp = get(); // expected-note{{also accessed here}} | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | void readOnlyLoop(Test *a) { | 
 |   while (condition()) { | 
 |     use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} | 
 |   } | 
 | } | 
 |  | 
 | void readInIterationLoop() { | 
 |   for (Test *a in get()) | 
 |     use(a.weakProp); // no-warning | 
 | } | 
 |  | 
 | void readDoubleLevelAccessInLoop() { | 
 |   for (Test *a in get()) { | 
 |     use(a.strongProp.weakProp); // no-warning | 
 |   } | 
 | } | 
 |  | 
 | void readParameterInLoop(Test *a) { | 
 |   for (id unused in get()) { | 
 |     use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} | 
 |     (void)unused; | 
 |   } | 
 | } | 
 |  | 
 | void readGlobalInLoop() { | 
 |   static __weak id a; | 
 |   for (id unused in get()) { | 
 |     use(a); // expected-warning{{weak variable 'a' is accessed multiple times in this function}} | 
 |     (void)unused; | 
 |   } | 
 | } | 
 |  | 
 | void doWhileLoop(Test *a) { | 
 |   do { | 
 |     use(a.weakProp); // no-warning | 
 |   } while(0); | 
 | } | 
 |  | 
 | struct S { | 
 |   int a; | 
 |   id b; | 
 | }; | 
 |  | 
 | @interface C | 
 | @property S p; | 
 | @end | 
 |  | 
 | void test_list_init(C *c) { | 
 |   c.p = {0, c.p.b}; | 
 | } | 
 |  | 
 | @interface Test (Methods) | 
 | @end | 
 |  | 
 | @implementation Test (Methods) | 
 | - (void)basicCorrectnessTest { | 
 |   use(self.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this method but may be unpredictably set to nil; assign to a strong variable to keep the object alive}} | 
 |   use(self.weakProp); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | - (void)ivars { | 
 |   use(weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times in this method but may be unpredictably set to nil; assign to a strong variable to keep the object alive}} | 
 |   use(weakIvar); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | - (void)doubleLevelAccessForSelf { | 
 |   use(self.strongProp.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} | 
 |   use(self.strongProp.weakProp); // expected-note{{also accessed here}} | 
 |  | 
 |   use(self->ivar.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} | 
 |   use(self->ivar.weakProp); // expected-note{{also accessed here}} | 
 |  | 
 |   use(self->ivar->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}} | 
 |   use(self->ivar->weakIvar); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | - (void)distinctFromOther:(Test *)other { | 
 |   use(self.strongProp.weakProp); // no-warning | 
 |   use(other.strongProp.weakProp); // no-warning | 
 |  | 
 |   use(self->ivar.weakProp); // no-warning | 
 |   use(other->ivar.weakProp); // no-warning | 
 |  | 
 |   use(self.strongProp->weakIvar); // no-warning | 
 |   use(other.strongProp->weakIvar); // no-warning | 
 | } | 
 | @end | 
 |  | 
 | @interface Base1 | 
 | @end | 
 | @interface Sub1 : Base1 | 
 | @end | 
 | @interface Sub1(cat) | 
 | -(id)prop; | 
 | @end | 
 |  | 
 | void test1(Sub1 *s) { | 
 |   use([s prop]); | 
 |   use([s prop]); | 
 | } | 
 |  | 
 | @interface Base1(cat) | 
 | @property (weak) id prop; | 
 | @end | 
 |  | 
 | void test2(Sub1 *s) { | 
 |   // This does not warn because the "prop" in "Base1(cat)" was introduced | 
 |   // after the method declaration and we don't find it as overridden. | 
 |   // Always looking for overridden methods after the method declaration is expensive | 
 |   // and it's not clear it is worth it currently. | 
 |   use([s prop]); | 
 |   use([s prop]); | 
 | } | 
 |  | 
 |  | 
 | class Wrapper { | 
 |   Test *a; | 
 |  | 
 | public: | 
 |   void fields() { | 
 |     use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function but may be unpredictably set to nil; assign to a strong variable to keep the object alive}} | 
 |     use(a.weakProp); // expected-note{{also accessed here}} | 
 |   } | 
 |  | 
 |   void distinctFromOther(Test *b, const Wrapper &w) { | 
 |     use(a.weakProp); // no-warning | 
 |     use(b.weakProp); // no-warning | 
 |     use(w.a.weakProp); // no-warning | 
 |   } | 
 |  | 
 |   static void doubleLevelAccessField(const Wrapper &x, const Wrapper &y) { | 
 |     use(x.a.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} | 
 |     use(y.a.weakProp); // expected-note{{also accessed here}} | 
 |   } | 
 | }; | 
 |  | 
 |  | 
 | // ----------------------- | 
 | // False positives | 
 | // ----------------------- | 
 |  | 
 | // Most of these would require flow-sensitive analysis to silence correctly. | 
 |  | 
 | void assignNil(Test *a) { | 
 |   if (condition()) | 
 |     a.weakProp = nil; // expected-note{{also accessed here}} | 
 |  | 
 |   use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} | 
 | } | 
 |  | 
 | void branch(Test *a) { | 
 |   if (condition()) | 
 |     use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} | 
 |   else | 
 |     use(a.weakProp); // expected-note{{also accessed here}} | 
 | } | 
 |  | 
 | void doubleLevelAccess(Test *a, Test *b) { | 
 |   use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} | 
 |   use(b.strongProp.weakProp); // expected-note{{also accessed here}} | 
 |  | 
 |   use(a.weakProp.weakProp); // no-warning | 
 | } | 
 |  | 
 | void doubleLevelAccessIvar(Test *a, Test *b) { | 
 |   use(a->ivar.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} | 
 |   use(b->ivar.weakProp); // expected-note{{also accessed here}} | 
 |  | 
 |   use(a.strongProp.weakProp); // no-warning | 
 | } | 
 |  | 
 | @interface X | 
 | @end | 
 |  | 
 | @implementation X | 
 | - (int) warningAboutWeakVariableInsideTypeof { | 
 |     __typeof__(self) __weak weakSelf = self; | 
 |     ^(){ | 
 |         __typeof__(weakSelf) blockSelf = weakSelf; | 
 |         use(blockSelf); | 
 |     }(); | 
 |     return sizeof(weakSelf); | 
 | } | 
 | @end | 
 |  | 
 | @interface NSNull | 
 | + (NSNull *)null; | 
 | @end | 
 |  | 
 | @interface INTF @end | 
 |  | 
 | @implementation INTF | 
 | - (void) Meth : (id) data | 
 | { | 
 |   data = data ?: NSNull.null; | 
 | } | 
 | @end | 
 |  | 
 | // This used to crash in WeakObjectProfileTy::getBaseInfo when getBase() was | 
 | // called on an ObjCPropertyRefExpr object whose receiver was an interface. | 
 |  | 
 | @class NSString; | 
 | @interface NSBundle | 
 | +(NSBundle *)foo; | 
 | @property (class, strong) NSBundle *foo2; | 
 | @property (strong) NSString *prop; | 
 | @property(weak) NSString *weakProp; | 
 | @end | 
 |  | 
 | @interface NSBundle2 : NSBundle | 
 | @end | 
 |  | 
 | void foo() { | 
 |   NSString * t = NSBundle.foo.prop; | 
 |   use(NSBundle.foo.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} | 
 |   use(NSBundle2.foo.weakProp); // expected-note{{also accessed here}} | 
 |  | 
 |   NSString * t2 = NSBundle.foo2.prop; | 
 |   use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} | 
 |   use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}} | 
 |   decltype([NSBundle2.foo2 weakProp]) t3; | 
 |   decltype(NSBundle2.foo2.weakProp) t4; | 
 |   __typeof__(NSBundle2.foo2.weakProp) t5; | 
 | } | 
 |  | 
 | // This used to crash in the constructor of WeakObjectProfileTy when a | 
 | // DeclRefExpr was passed that didn't reference a VarDecl. | 
 |  | 
 | typedef INTF * INTFPtrTy; | 
 |  | 
 | enum E { | 
 |   e1 | 
 | }; | 
 |  | 
 | void foo1() { | 
 |   INTFPtrTy tmp = (INTFPtrTy)e1; | 
 | #if __has_feature(objc_arc) | 
 | // expected-error@-2{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}} | 
 | #endif | 
 | } | 
 |  | 
 | @class NSString; | 
 | static NSString* const kGlobal = @""; | 
 |  | 
 | @interface NSDictionary | 
 | - (id)objectForKeyedSubscript:(id)key; | 
 | @end | 
 |  | 
 | @interface WeakProp | 
 | @property (weak) NSDictionary *nd; | 
 | @end | 
 |  | 
 | @implementation WeakProp | 
 | -(void)m { | 
 |   (void)self.nd[@""]; // no warning | 
 | } | 
 | @end |