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