1f4a2713aSLionel Sambuc// 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 2f4a2713aSLionel Sambuc 3f4a2713aSLionel Sambuc@interface Test { 4f4a2713aSLionel Sambuc@public 5f4a2713aSLionel Sambuc Test *ivar; 6f4a2713aSLionel Sambuc __weak id weakIvar; 7f4a2713aSLionel Sambuc} 8f4a2713aSLionel Sambuc@property(weak) Test *weakProp; 9f4a2713aSLionel Sambuc@property(strong) Test *strongProp; 10f4a2713aSLionel Sambuc 11f4a2713aSLionel Sambuc- (__weak id)implicitProp; 12f4a2713aSLionel Sambuc 13f4a2713aSLionel Sambuc+ (__weak id)weakProp; 14f4a2713aSLionel Sambuc@end 15f4a2713aSLionel Sambuc 16f4a2713aSLionel Sambucextern void use(id); 17f4a2713aSLionel Sambucextern id get(); 18f4a2713aSLionel Sambucextern bool condition(); 19f4a2713aSLionel Sambuc#define nil ((id)0) 20f4a2713aSLionel Sambuc 21f4a2713aSLionel Sambucvoid sanity(Test *a) { 22f4a2713aSLionel Sambuc 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}} 23f4a2713aSLionel Sambuc use(a.weakProp); // expected-note{{also accessed here}} 24f4a2713aSLionel Sambuc 25f4a2713aSLionel Sambuc use(a.strongProp); 26f4a2713aSLionel Sambuc use(a.strongProp); // no-warning 27f4a2713aSLionel Sambuc 28f4a2713aSLionel Sambuc use(a.weakProp); // expected-note{{also accessed here}} 29f4a2713aSLionel Sambuc} 30f4a2713aSLionel Sambuc 31f4a2713aSLionel Sambucvoid singleUse(Test *a) { 32f4a2713aSLionel Sambuc use(a.weakProp); // no-warning 33f4a2713aSLionel Sambuc use(a.strongProp); // no-warning 34f4a2713aSLionel Sambuc} 35f4a2713aSLionel Sambuc 36f4a2713aSLionel Sambucvoid assignsOnly(Test *a) { 37f4a2713aSLionel Sambuc a.weakProp = get(); // no-warning 38f4a2713aSLionel Sambuc 39f4a2713aSLionel Sambuc id next = get(); 40f4a2713aSLionel Sambuc if (next) 41f4a2713aSLionel Sambuc a.weakProp = next; // no-warning 42f4a2713aSLionel Sambuc 43f4a2713aSLionel Sambuc a->weakIvar = get(); // no-warning 44f4a2713aSLionel Sambuc next = get(); 45f4a2713aSLionel Sambuc if (next) 46f4a2713aSLionel Sambuc a->weakIvar = next; // no-warning 47f4a2713aSLionel Sambuc 48f4a2713aSLionel Sambuc extern __weak id x; 49f4a2713aSLionel Sambuc x = get(); // no-warning 50f4a2713aSLionel Sambuc next = get(); 51f4a2713aSLionel Sambuc if (next) 52f4a2713aSLionel Sambuc x = next; // no-warning 53f4a2713aSLionel Sambuc} 54f4a2713aSLionel Sambuc 55f4a2713aSLionel Sambucvoid assignThenRead(Test *a) { 56f4a2713aSLionel Sambuc a.weakProp = get(); // expected-note{{also accessed here}} 57f4a2713aSLionel Sambuc use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} 58f4a2713aSLionel Sambuc} 59f4a2713aSLionel Sambuc 60f4a2713aSLionel Sambucvoid twoVariables(Test *a, Test *b) { 61f4a2713aSLionel Sambuc use(a.weakProp); // no-warning 62f4a2713aSLionel Sambuc use(b.weakProp); // no-warning 63f4a2713aSLionel Sambuc} 64f4a2713aSLionel Sambuc 65f4a2713aSLionel Sambucvoid doubleLevelAccess(Test *a) { 66f4a2713aSLionel Sambuc 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}} 67f4a2713aSLionel Sambuc use(a.strongProp.weakProp); // expected-note{{also accessed here}} 68f4a2713aSLionel Sambuc} 69f4a2713aSLionel Sambuc 70f4a2713aSLionel Sambucvoid doubleLevelAccessIvar(Test *a) { 71f4a2713aSLionel Sambuc use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} 72f4a2713aSLionel Sambuc use(a.strongProp.weakProp); // expected-note{{also accessed here}} 73f4a2713aSLionel Sambuc} 74f4a2713aSLionel Sambuc 75f4a2713aSLionel Sambucvoid implicitProperties(Test *a) { 76f4a2713aSLionel Sambuc use(a.implicitProp); // expected-warning{{weak implicit property 'implicitProp' is accessed multiple times}} 77f4a2713aSLionel Sambuc use(a.implicitProp); // expected-note{{also accessed here}} 78f4a2713aSLionel Sambuc} 79f4a2713aSLionel Sambuc 80f4a2713aSLionel Sambucvoid classProperties() { 81f4a2713aSLionel Sambuc use(Test.weakProp); // expected-warning{{weak implicit property 'weakProp' is accessed multiple times}} 82f4a2713aSLionel Sambuc use(Test.weakProp); // expected-note{{also accessed here}} 83f4a2713aSLionel Sambuc} 84f4a2713aSLionel Sambuc 85f4a2713aSLionel Sambucvoid classPropertiesAreDifferent(Test *a) { 86f4a2713aSLionel Sambuc use(Test.weakProp); // no-warning 87f4a2713aSLionel Sambuc use(a.weakProp); // no-warning 88f4a2713aSLionel Sambuc use(a.strongProp.weakProp); // no-warning 89f4a2713aSLionel Sambuc} 90f4a2713aSLionel Sambuc 91f4a2713aSLionel Sambucvoid ivars(Test *a) { 92f4a2713aSLionel Sambuc use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}} 93f4a2713aSLionel Sambuc use(a->weakIvar); // expected-note{{also accessed here}} 94f4a2713aSLionel Sambuc} 95f4a2713aSLionel Sambuc 96f4a2713aSLionel Sambucvoid globals() { 97f4a2713aSLionel Sambuc extern __weak id a; 98f4a2713aSLionel Sambuc use(a); // expected-warning{{weak variable 'a' is accessed multiple times}} 99f4a2713aSLionel Sambuc use(a); // expected-note{{also accessed here}} 100f4a2713aSLionel Sambuc} 101f4a2713aSLionel Sambuc 102f4a2713aSLionel Sambucvoid messageGetter(Test *a) { 103f4a2713aSLionel Sambuc use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}} 104f4a2713aSLionel Sambuc use([a weakProp]); // expected-note{{also accessed here}} 105f4a2713aSLionel Sambuc} 106f4a2713aSLionel Sambuc 107f4a2713aSLionel Sambucvoid messageSetter(Test *a) { 108f4a2713aSLionel Sambuc [a setWeakProp:get()]; // no-warning 109f4a2713aSLionel Sambuc [a setWeakProp:get()]; // no-warning 110f4a2713aSLionel Sambuc} 111f4a2713aSLionel Sambuc 112f4a2713aSLionel Sambucvoid messageSetterAndGetter(Test *a) { 113f4a2713aSLionel Sambuc [a setWeakProp:get()]; // expected-note{{also accessed here}} 114f4a2713aSLionel Sambuc use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}} 115f4a2713aSLionel Sambuc} 116f4a2713aSLionel Sambuc 117f4a2713aSLionel Sambucvoid mixDotAndMessageSend(Test *a, Test *b) { 118f4a2713aSLionel Sambuc use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} 119f4a2713aSLionel Sambuc use([a weakProp]); // expected-note{{also accessed here}} 120f4a2713aSLionel Sambuc 121f4a2713aSLionel Sambuc use([b weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}} 122f4a2713aSLionel Sambuc use(b.weakProp); // expected-note{{also accessed here}} 123f4a2713aSLionel Sambuc} 124f4a2713aSLionel Sambuc 125f4a2713aSLionel Sambuc 126f4a2713aSLionel Sambucvoid assignToStrongWrongInit(Test *a) { 127f4a2713aSLionel Sambuc id val = a.weakProp; // expected-note{{also accessed here}} 128f4a2713aSLionel Sambuc use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} 129f4a2713aSLionel Sambuc} 130f4a2713aSLionel Sambuc 131f4a2713aSLionel Sambucvoid assignToStrongWrong(Test *a) { 132f4a2713aSLionel Sambuc id val; 133f4a2713aSLionel Sambuc val = a.weakProp; // expected-note{{also accessed here}} 134f4a2713aSLionel Sambuc use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} 135f4a2713aSLionel Sambuc} 136f4a2713aSLionel Sambuc 137f4a2713aSLionel Sambucvoid assignToIvarWrong(Test *a) { 138f4a2713aSLionel Sambuc a->weakIvar = get(); // expected-note{{also accessed here}} 139f4a2713aSLionel Sambuc use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}} 140f4a2713aSLionel Sambuc} 141f4a2713aSLionel Sambuc 142f4a2713aSLionel Sambucvoid assignToGlobalWrong() { 143f4a2713aSLionel Sambuc extern __weak id a; 144f4a2713aSLionel Sambuc a = get(); // expected-note{{also accessed here}} 145f4a2713aSLionel Sambuc use(a); // expected-warning{{weak variable 'a' is accessed multiple times}} 146f4a2713aSLionel Sambuc} 147f4a2713aSLionel Sambuc 148f4a2713aSLionel Sambucvoid assignToStrongOK(Test *a) { 149f4a2713aSLionel Sambuc if (condition()) { 150f4a2713aSLionel Sambuc id val = a.weakProp; // no-warning 151f4a2713aSLionel Sambuc (void)val; 152f4a2713aSLionel Sambuc } else { 153f4a2713aSLionel Sambuc id val; 154f4a2713aSLionel Sambuc val = a.weakProp; // no-warning 155f4a2713aSLionel Sambuc (void)val; 156f4a2713aSLionel Sambuc } 157f4a2713aSLionel Sambuc} 158f4a2713aSLionel Sambuc 159f4a2713aSLionel Sambucvoid assignToStrongConditional(Test *a) { 160f4a2713aSLionel Sambuc id val = (condition() ? a.weakProp : a.weakProp); // no-warning 161f4a2713aSLionel Sambuc id val2 = a.implicitProp ?: a.implicitProp; // no-warning 162f4a2713aSLionel Sambuc} 163f4a2713aSLionel Sambuc 164f4a2713aSLionel Sambucvoid testBlock(Test *a) { 165f4a2713aSLionel Sambuc use(a.weakProp); // no-warning 166f4a2713aSLionel Sambuc 167f4a2713aSLionel Sambuc use(^{ 168f4a2713aSLionel Sambuc use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this block}} 169f4a2713aSLionel Sambuc use(a.weakProp); // expected-note{{also accessed here}} 170f4a2713aSLionel Sambuc }); 171f4a2713aSLionel Sambuc} 172f4a2713aSLionel Sambuc 173f4a2713aSLionel Sambucvoid assignToStrongWithCasts(Test *a) { 174f4a2713aSLionel Sambuc if (condition()) { 175f4a2713aSLionel Sambuc Test *val = (Test *)a.weakProp; // no-warning 176f4a2713aSLionel Sambuc (void)val; 177f4a2713aSLionel Sambuc } else { 178f4a2713aSLionel Sambuc id val; 179f4a2713aSLionel Sambuc val = (Test *)a.weakProp; // no-warning 180f4a2713aSLionel Sambuc (void)val; 181f4a2713aSLionel Sambuc } 182f4a2713aSLionel Sambuc} 183f4a2713aSLionel Sambuc 184f4a2713aSLionel Sambucvoid assignToStrongWithMessages(Test *a) { 185f4a2713aSLionel Sambuc if (condition()) { 186f4a2713aSLionel Sambuc id val = [a weakProp]; // no-warning 187f4a2713aSLionel Sambuc (void)val; 188f4a2713aSLionel Sambuc } else { 189f4a2713aSLionel Sambuc id val; 190f4a2713aSLionel Sambuc val = [a weakProp]; // no-warning 191f4a2713aSLionel Sambuc (void)val; 192f4a2713aSLionel Sambuc } 193f4a2713aSLionel Sambuc} 194f4a2713aSLionel Sambuc 195f4a2713aSLionel Sambuc 196f4a2713aSLionel Sambucvoid assignAfterRead(Test *a) { 197f4a2713aSLionel Sambuc // Special exception for a single read before any writes. 198f4a2713aSLionel Sambuc if (!a.weakProp) // no-warning 199f4a2713aSLionel Sambuc a.weakProp = get(); // no-warning 200f4a2713aSLionel Sambuc} 201f4a2713aSLionel Sambuc 202f4a2713aSLionel Sambucvoid readOnceWriteMany(Test *a) { 203f4a2713aSLionel Sambuc if (!a.weakProp) { // no-warning 204f4a2713aSLionel Sambuc a.weakProp = get(); // no-warning 205f4a2713aSLionel Sambuc a.weakProp = get(); // no-warning 206f4a2713aSLionel Sambuc } 207f4a2713aSLionel Sambuc} 208f4a2713aSLionel Sambuc 209f4a2713aSLionel Sambucvoid readOnceAfterWrite(Test *a) { 210f4a2713aSLionel Sambuc a.weakProp = get(); // expected-note{{also accessed here}} 211f4a2713aSLionel Sambuc if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} 212f4a2713aSLionel Sambuc a.weakProp = get(); // expected-note{{also accessed here}} 213f4a2713aSLionel Sambuc } 214f4a2713aSLionel Sambuc} 215f4a2713aSLionel Sambuc 216f4a2713aSLionel Sambucvoid readOnceWriteManyLoops(Test *a, Test *b, Test *c, Test *d, Test *e) { 217f4a2713aSLionel Sambuc while (condition()) { 218f4a2713aSLionel Sambuc if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} 219f4a2713aSLionel Sambuc a.weakProp = get(); // expected-note{{also accessed here}} 220f4a2713aSLionel Sambuc a.weakProp = get(); // expected-note{{also accessed here}} 221f4a2713aSLionel Sambuc } 222f4a2713aSLionel Sambuc } 223f4a2713aSLionel Sambuc 224f4a2713aSLionel Sambuc do { 225f4a2713aSLionel Sambuc if (!b.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} 226f4a2713aSLionel Sambuc b.weakProp = get(); // expected-note{{also accessed here}} 227f4a2713aSLionel Sambuc b.weakProp = get(); // expected-note{{also accessed here}} 228f4a2713aSLionel Sambuc } 229f4a2713aSLionel Sambuc } while (condition()); 230f4a2713aSLionel Sambuc 231f4a2713aSLionel Sambuc for (id x = get(); x; x = get()) { 232f4a2713aSLionel Sambuc if (!c.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} 233f4a2713aSLionel Sambuc c.weakProp = get(); // expected-note{{also accessed here}} 234f4a2713aSLionel Sambuc c.weakProp = get(); // expected-note{{also accessed here}} 235f4a2713aSLionel Sambuc } 236f4a2713aSLionel Sambuc } 237f4a2713aSLionel Sambuc 238f4a2713aSLionel Sambuc for (id x in get()) { 239f4a2713aSLionel Sambuc if (!d.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} 240f4a2713aSLionel Sambuc d.weakProp = get(); // expected-note{{also accessed here}} 241f4a2713aSLionel Sambuc d.weakProp = get(); // expected-note{{also accessed here}} 242f4a2713aSLionel Sambuc } 243f4a2713aSLionel Sambuc } 244f4a2713aSLionel Sambuc 245f4a2713aSLionel Sambuc int array[] = { 1, 2, 3 }; 246f4a2713aSLionel Sambuc for (int i : array) { 247f4a2713aSLionel Sambuc if (!e.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} 248f4a2713aSLionel Sambuc e.weakProp = get(); // expected-note{{also accessed here}} 249f4a2713aSLionel Sambuc e.weakProp = get(); // expected-note{{also accessed here}} 250f4a2713aSLionel Sambuc } 251f4a2713aSLionel Sambuc } 252f4a2713aSLionel Sambuc} 253f4a2713aSLionel Sambuc 254f4a2713aSLionel Sambucvoid readOnlyLoop(Test *a) { 255f4a2713aSLionel Sambuc while (condition()) { 256f4a2713aSLionel Sambuc use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} 257f4a2713aSLionel Sambuc } 258f4a2713aSLionel Sambuc} 259f4a2713aSLionel Sambuc 260f4a2713aSLionel Sambucvoid readInIterationLoop() { 261f4a2713aSLionel Sambuc for (Test *a in get()) 262f4a2713aSLionel Sambuc use(a.weakProp); // no-warning 263f4a2713aSLionel Sambuc} 264f4a2713aSLionel Sambuc 265f4a2713aSLionel Sambucvoid readDoubleLevelAccessInLoop() { 266f4a2713aSLionel Sambuc for (Test *a in get()) { 267f4a2713aSLionel Sambuc use(a.strongProp.weakProp); // no-warning 268f4a2713aSLionel Sambuc } 269f4a2713aSLionel Sambuc} 270f4a2713aSLionel Sambuc 271f4a2713aSLionel Sambucvoid readParameterInLoop(Test *a) { 272f4a2713aSLionel Sambuc for (id unused in get()) { 273f4a2713aSLionel Sambuc use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}} 274f4a2713aSLionel Sambuc (void)unused; 275f4a2713aSLionel Sambuc } 276f4a2713aSLionel Sambuc} 277f4a2713aSLionel Sambuc 278f4a2713aSLionel Sambucvoid readGlobalInLoop() { 279f4a2713aSLionel Sambuc static __weak id a; 280f4a2713aSLionel Sambuc for (id unused in get()) { 281f4a2713aSLionel Sambuc use(a); // expected-warning{{weak variable 'a' is accessed multiple times in this function}} 282f4a2713aSLionel Sambuc (void)unused; 283f4a2713aSLionel Sambuc } 284f4a2713aSLionel Sambuc} 285f4a2713aSLionel Sambuc 286f4a2713aSLionel Sambucvoid doWhileLoop(Test *a) { 287f4a2713aSLionel Sambuc do { 288f4a2713aSLionel Sambuc use(a.weakProp); // no-warning 289f4a2713aSLionel Sambuc } while(0); 290f4a2713aSLionel Sambuc} 291f4a2713aSLionel Sambuc 292f4a2713aSLionel Sambuc 293f4a2713aSLionel Sambuc@interface Test (Methods) 294f4a2713aSLionel Sambuc@end 295f4a2713aSLionel Sambuc 296f4a2713aSLionel Sambuc@implementation Test (Methods) 297f4a2713aSLionel Sambuc- (void)sanity { 298f4a2713aSLionel Sambuc 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}} 299f4a2713aSLionel Sambuc use(self.weakProp); // expected-note{{also accessed here}} 300f4a2713aSLionel Sambuc} 301f4a2713aSLionel Sambuc 302f4a2713aSLionel Sambuc- (void)ivars { 303f4a2713aSLionel Sambuc 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}} 304f4a2713aSLionel Sambuc use(weakIvar); // expected-note{{also accessed here}} 305f4a2713aSLionel Sambuc} 306f4a2713aSLionel Sambuc 307f4a2713aSLionel Sambuc- (void)doubleLevelAccessForSelf { 308f4a2713aSLionel Sambuc use(self.strongProp.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} 309f4a2713aSLionel Sambuc use(self.strongProp.weakProp); // expected-note{{also accessed here}} 310f4a2713aSLionel Sambuc 311f4a2713aSLionel Sambuc use(self->ivar.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} 312f4a2713aSLionel Sambuc use(self->ivar.weakProp); // expected-note{{also accessed here}} 313f4a2713aSLionel Sambuc 314f4a2713aSLionel Sambuc use(self->ivar->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}} 315f4a2713aSLionel Sambuc use(self->ivar->weakIvar); // expected-note{{also accessed here}} 316f4a2713aSLionel Sambuc} 317f4a2713aSLionel Sambuc 318f4a2713aSLionel Sambuc- (void)distinctFromOther:(Test *)other { 319f4a2713aSLionel Sambuc use(self.strongProp.weakProp); // no-warning 320f4a2713aSLionel Sambuc use(other.strongProp.weakProp); // no-warning 321f4a2713aSLionel Sambuc 322f4a2713aSLionel Sambuc use(self->ivar.weakProp); // no-warning 323f4a2713aSLionel Sambuc use(other->ivar.weakProp); // no-warning 324f4a2713aSLionel Sambuc 325f4a2713aSLionel Sambuc use(self.strongProp->weakIvar); // no-warning 326f4a2713aSLionel Sambuc use(other.strongProp->weakIvar); // no-warning 327f4a2713aSLionel Sambuc} 328f4a2713aSLionel Sambuc@end 329f4a2713aSLionel Sambuc 330f4a2713aSLionel Sambuc@interface Base1 331f4a2713aSLionel Sambuc@end 332f4a2713aSLionel Sambuc@interface Sub1 : Base1 333f4a2713aSLionel Sambuc@end 334f4a2713aSLionel Sambuc@interface Sub1(cat) 335f4a2713aSLionel Sambuc-(id)prop; 336f4a2713aSLionel Sambuc@end 337f4a2713aSLionel Sambuc 338f4a2713aSLionel Sambucvoid test1(Sub1 *s) { 339f4a2713aSLionel Sambuc use([s prop]); 340f4a2713aSLionel Sambuc use([s prop]); 341f4a2713aSLionel Sambuc} 342f4a2713aSLionel Sambuc 343f4a2713aSLionel Sambuc@interface Base1(cat) 344f4a2713aSLionel Sambuc@property (weak) id prop; 345f4a2713aSLionel Sambuc@end 346f4a2713aSLionel Sambuc 347f4a2713aSLionel Sambucvoid test2(Sub1 *s) { 348f4a2713aSLionel Sambuc // This does not warn because the "prop" in "Base1(cat)" was introduced 349f4a2713aSLionel Sambuc // after the method declaration and we don't find it as overridden. 350f4a2713aSLionel Sambuc // Always looking for overridden methods after the method declaration is expensive 351f4a2713aSLionel Sambuc // and it's not clear it is worth it currently. 352f4a2713aSLionel Sambuc use([s prop]); 353f4a2713aSLionel Sambuc use([s prop]); 354f4a2713aSLionel Sambuc} 355f4a2713aSLionel Sambuc 356f4a2713aSLionel Sambuc 357f4a2713aSLionel Sambucclass Wrapper { 358f4a2713aSLionel Sambuc Test *a; 359f4a2713aSLionel Sambuc 360f4a2713aSLionel Sambucpublic: 361f4a2713aSLionel Sambuc void fields() { 362f4a2713aSLionel Sambuc 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}} 363f4a2713aSLionel Sambuc use(a.weakProp); // expected-note{{also accessed here}} 364f4a2713aSLionel Sambuc } 365f4a2713aSLionel Sambuc 366f4a2713aSLionel Sambuc void distinctFromOther(Test *b, const Wrapper &w) { 367f4a2713aSLionel Sambuc use(a.weakProp); // no-warning 368f4a2713aSLionel Sambuc use(b.weakProp); // no-warning 369f4a2713aSLionel Sambuc use(w.a.weakProp); // no-warning 370f4a2713aSLionel Sambuc } 371f4a2713aSLionel Sambuc 372f4a2713aSLionel Sambuc static void doubleLevelAccessField(const Wrapper &x, const Wrapper &y) { 373f4a2713aSLionel Sambuc use(x.a.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} 374f4a2713aSLionel Sambuc use(y.a.weakProp); // expected-note{{also accessed here}} 375f4a2713aSLionel Sambuc } 376f4a2713aSLionel Sambuc}; 377f4a2713aSLionel Sambuc 378f4a2713aSLionel Sambuc 379f4a2713aSLionel Sambuc// ----------------------- 380f4a2713aSLionel Sambuc// False positives 381f4a2713aSLionel Sambuc// ----------------------- 382f4a2713aSLionel Sambuc 383f4a2713aSLionel Sambuc// Most of these would require flow-sensitive analysis to silence correctly. 384f4a2713aSLionel Sambuc 385f4a2713aSLionel Sambucvoid assignNil(Test *a) { 386f4a2713aSLionel Sambuc if (condition()) 387f4a2713aSLionel Sambuc a.weakProp = nil; // expected-note{{also accessed here}} 388f4a2713aSLionel Sambuc 389f4a2713aSLionel Sambuc use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} 390f4a2713aSLionel Sambuc} 391f4a2713aSLionel Sambuc 392f4a2713aSLionel Sambucvoid branch(Test *a) { 393f4a2713aSLionel Sambuc if (condition()) 394f4a2713aSLionel Sambuc use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}} 395f4a2713aSLionel Sambuc else 396f4a2713aSLionel Sambuc use(a.weakProp); // expected-note{{also accessed here}} 397f4a2713aSLionel Sambuc} 398f4a2713aSLionel Sambuc 399f4a2713aSLionel Sambucvoid doubleLevelAccess(Test *a, Test *b) { 400f4a2713aSLionel Sambuc use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} 401f4a2713aSLionel Sambuc use(b.strongProp.weakProp); // expected-note{{also accessed here}} 402f4a2713aSLionel Sambuc 403f4a2713aSLionel Sambuc use(a.weakProp.weakProp); // no-warning 404f4a2713aSLionel Sambuc} 405f4a2713aSLionel Sambuc 406f4a2713aSLionel Sambucvoid doubleLevelAccessIvar(Test *a, Test *b) { 407f4a2713aSLionel Sambuc use(a->ivar.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} 408f4a2713aSLionel Sambuc use(b->ivar.weakProp); // expected-note{{also accessed here}} 409f4a2713aSLionel Sambuc 410f4a2713aSLionel Sambuc use(a.strongProp.weakProp); // no-warning 411f4a2713aSLionel Sambuc} 412f4a2713aSLionel Sambuc 413f4a2713aSLionel Sambuc// rdar://13942025 414f4a2713aSLionel Sambuc@interface X 415f4a2713aSLionel Sambuc@end 416f4a2713aSLionel Sambuc 417f4a2713aSLionel Sambuc@implementation X 418f4a2713aSLionel Sambuc- (int) warningAboutWeakVariableInsideTypeof { 419f4a2713aSLionel Sambuc __typeof__(self) __weak weakSelf = self; 420f4a2713aSLionel Sambuc ^(){ 421f4a2713aSLionel Sambuc __typeof__(weakSelf) blockSelf = weakSelf; 422f4a2713aSLionel Sambuc use(blockSelf); 423f4a2713aSLionel Sambuc }(); 424f4a2713aSLionel Sambuc return sizeof(weakSelf); 425f4a2713aSLionel Sambuc} 426f4a2713aSLionel Sambuc@end 427f4a2713aSLionel Sambuc 428*0a6a1f1dSLionel Sambuc// rdar://19053620 429*0a6a1f1dSLionel Sambuc@interface NSNull 430*0a6a1f1dSLionel Sambuc+ (NSNull *)null; 431*0a6a1f1dSLionel Sambuc@end 432*0a6a1f1dSLionel Sambuc 433*0a6a1f1dSLionel Sambuc@interface INTF @end 434*0a6a1f1dSLionel Sambuc 435*0a6a1f1dSLionel Sambuc@implementation INTF 436*0a6a1f1dSLionel Sambuc- (void) Meth : (id) data 437*0a6a1f1dSLionel Sambuc{ 438*0a6a1f1dSLionel Sambuc data = data ?: NSNull.null; 439*0a6a1f1dSLionel Sambuc} 440*0a6a1f1dSLionel Sambuc@end 441*0a6a1f1dSLionel Sambuc 442