brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.5 KiB · aaf8256 Raw
512 lines · plain
1// 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 %s2// 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 %s3 4@interface Test {5@public6  Test *ivar;7  __weak id weakIvar;8}9@property(weak) Test *weakProp;10@property(strong) Test *strongProp;11 12- (__weak id)implicitProp;13 14+ (__weak id)weakProp;15@end16 17extern void use(id);18extern id get();19extern bool condition();20#define nil ((id)0)21 22void basicCorrectnessTest(Test *a) {23  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}}24  use(a.weakProp); // expected-note{{also accessed here}}25 26  use(a.strongProp);27  use(a.strongProp); // no-warning28 29  use(a.weakProp); // expected-note{{also accessed here}}30}31 32void singleUse(Test *a) {33  use(a.weakProp); // no-warning34  use(a.strongProp); // no-warning35}36 37void assignsOnly(Test *a) {38  a.weakProp = get(); // no-warning39 40  id next = get();41  if (next)42    a.weakProp = next; // no-warning43 44  a->weakIvar = get(); // no-warning45  next = get();46  if (next)47    a->weakIvar = next; // no-warning48 49  extern __weak id x;50  x = get(); // no-warning51  next = get();52  if (next)53    x = next; // no-warning54}55 56void assignThenRead(Test *a) {57  a.weakProp = get(); // expected-note{{also accessed here}}58  use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}59}60 61void twoVariables(Test *a, Test *b) {62  use(a.weakProp); // no-warning63  use(b.weakProp); // no-warning64}65 66void doubleLevelAccess(Test *a) {67  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}}68  use(a.strongProp.weakProp); // expected-note{{also accessed here}}69}70 71void doubleLevelAccessIvar(Test *a) {72  use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}73  use(a.strongProp.weakProp); // expected-note{{also accessed here}}74}75 76void implicitProperties(Test *a) {77  use(a.implicitProp); // expected-warning{{weak implicit property 'implicitProp' is accessed multiple times}}78  use(a.implicitProp); // expected-note{{also accessed here}}79}80 81void classProperties() {82  use(Test.weakProp); // expected-warning{{weak implicit property 'weakProp' is accessed multiple times}}83  use(Test.weakProp); // expected-note{{also accessed here}}84}85 86void classPropertiesAreDifferent(Test *a) {87  use(Test.weakProp); // no-warning88  use(a.weakProp); // no-warning89  use(a.strongProp.weakProp); // no-warning90}91 92void ivars(Test *a) {93  use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}94  use(a->weakIvar); // expected-note{{also accessed here}}95}96 97void globals() {98  extern __weak id a;99  use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}100  use(a); // expected-note{{also accessed here}}101}102 103void messageGetter(Test *a) {104  use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}105  use([a weakProp]); // expected-note{{also accessed here}}106}107 108void messageSetter(Test *a) {109  [a setWeakProp:get()]; // no-warning110  [a setWeakProp:get()]; // no-warning111}112 113void messageSetterAndGetter(Test *a) {114  [a setWeakProp:get()]; // expected-note{{also accessed here}}115  use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}116}117 118void mixDotAndMessageSend(Test *a, Test *b) {119  use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}120  use([a weakProp]); // expected-note{{also accessed here}}121 122  use([b weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}123  use(b.weakProp); // expected-note{{also accessed here}}124}125 126 127void assignToStrongWrongInit(Test *a) {128  id val = a.weakProp; // expected-note{{also accessed here}}129  use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}130}131 132void assignToStrongWrong(Test *a) {133  id val;134  val = a.weakProp; // expected-note{{also accessed here}}135  use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}136}137 138void assignToIvarWrong(Test *a) {139  a->weakIvar = get(); // expected-note{{also accessed here}}140  use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}141}142 143void assignToGlobalWrong() {144  extern __weak id a;145  a = get(); // expected-note{{also accessed here}}146  use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}147}148 149void assignToStrongOK(Test *a) {150  if (condition()) {151    id val = a.weakProp; // no-warning152    (void)val;153  } else {154    id val;155    val = a.weakProp; // no-warning156    (void)val;157  }158}159 160void assignToStrongConditional(Test *a) {161  id val = (condition() ? a.weakProp : a.weakProp); // no-warning162  id val2 = a.implicitProp ?: a.implicitProp; // no-warning163}164 165void testBlock(Test *a) {166  use(a.weakProp); // no-warning167 168  use(^{169    use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this block}}170    use(a.weakProp); // expected-note{{also accessed here}}171  });172}173 174void assignToStrongWithCasts(Test *a) {175  if (condition()) {176    Test *val = (Test *)a.weakProp; // no-warning177    (void)val;178  } else {179    id val;180    val = (Test *)a.weakProp; // no-warning181    (void)val;182  }183}184 185void assignToStrongWithMessages(Test *a) {186  if (condition()) {187    id val = [a weakProp]; // no-warning188    (void)val;189  } else {190    id val;191    val = [a weakProp]; // no-warning192    (void)val;193  }194}195 196 197void assignAfterRead(Test *a) {198  // Special exception for a single read before any writes.199  if (!a.weakProp) // no-warning200    a.weakProp = get(); // no-warning201}202 203void readOnceWriteMany(Test *a) {204  if (!a.weakProp) { // no-warning205    a.weakProp = get(); // no-warning206    a.weakProp = get(); // no-warning207  }208}209 210void readOnceAfterWrite(Test *a) {211  a.weakProp = get(); // expected-note{{also accessed here}}212  if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}213    a.weakProp = get(); // expected-note{{also accessed here}}214  }215}216 217void readOnceWriteManyLoops(Test *a, Test *b, Test *c, Test *d, Test *e) {218  while (condition()) {219    if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}220      a.weakProp = get(); // expected-note{{also accessed here}}221      a.weakProp = get(); // expected-note{{also accessed here}}222    }223  }224 225  do {226    if (!b.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}227      b.weakProp = get(); // expected-note{{also accessed here}}228      b.weakProp = get(); // expected-note{{also accessed here}}229    }230  } while (condition());231 232  for (id x = get(); x; x = get()) {233    if (!c.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}234      c.weakProp = get(); // expected-note{{also accessed here}}235      c.weakProp = get(); // expected-note{{also accessed here}}236    }237  }238 239  for (id x in get()) {240    if (!d.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}241      d.weakProp = get(); // expected-note{{also accessed here}}242      d.weakProp = get(); // expected-note{{also accessed here}}243    }244  }245 246  int array[] = { 1, 2, 3 };247  for (int i : array) {248    if (!e.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}249      e.weakProp = get(); // expected-note{{also accessed here}}250      e.weakProp = get(); // expected-note{{also accessed here}}251    }252  }253}254 255void readOnlyLoop(Test *a) {256  while (condition()) {257    use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}258  }259}260 261void readInIterationLoop() {262  for (Test *a in get())263    use(a.weakProp); // no-warning264}265 266void readDoubleLevelAccessInLoop() {267  for (Test *a in get()) {268    use(a.strongProp.weakProp); // no-warning269  }270}271 272void readParameterInLoop(Test *a) {273  for (id unused in get()) {274    use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}275    (void)unused;276  }277}278 279void readGlobalInLoop() {280  static __weak id a;281  for (id unused in get()) {282    use(a); // expected-warning{{weak variable 'a' is accessed multiple times in this function}}283    (void)unused;284  }285}286 287void doWhileLoop(Test *a) {288  do {289    use(a.weakProp); // no-warning290  } while(0);291}292 293struct S {294  int a;295  id b;296};297 298@interface C299@property S p;300@end301 302void test_list_init(C *c) {303  c.p = {0, c.p.b};304}305 306@interface Test (Methods)307@end308 309@implementation Test (Methods)310- (void)basicCorrectnessTest {311  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}}312  use(self.weakProp); // expected-note{{also accessed here}}313}314 315- (void)ivars {316  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}}317  use(weakIvar); // expected-note{{also accessed here}}318}319 320- (void)doubleLevelAccessForSelf {321  use(self.strongProp.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}322  use(self.strongProp.weakProp); // expected-note{{also accessed here}}323 324  use(self->ivar.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}325  use(self->ivar.weakProp); // expected-note{{also accessed here}}326 327  use(self->ivar->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}328  use(self->ivar->weakIvar); // expected-note{{also accessed here}}329}330 331- (void)distinctFromOther:(Test *)other {332  use(self.strongProp.weakProp); // no-warning333  use(other.strongProp.weakProp); // no-warning334 335  use(self->ivar.weakProp); // no-warning336  use(other->ivar.weakProp); // no-warning337 338  use(self.strongProp->weakIvar); // no-warning339  use(other.strongProp->weakIvar); // no-warning340}341@end342 343@interface Base1344@end345@interface Sub1 : Base1346@end347@interface Sub1(cat)348-(id)prop;349@end350 351void test1(Sub1 *s) {352  use([s prop]);353  use([s prop]);354}355 356@interface Base1(cat)357@property (weak) id prop;358@end359 360void test2(Sub1 *s) {361  // This does not warn because the "prop" in "Base1(cat)" was introduced362  // after the method declaration and we don't find it as overridden.363  // Always looking for overridden methods after the method declaration is expensive364  // and it's not clear it is worth it currently.365  use([s prop]);366  use([s prop]);367}368 369 370class Wrapper {371  Test *a;372 373public:374  void fields() {375    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}}376    use(a.weakProp); // expected-note{{also accessed here}}377  }378 379  void distinctFromOther(Test *b, const Wrapper &w) {380    use(a.weakProp); // no-warning381    use(b.weakProp); // no-warning382    use(w.a.weakProp); // no-warning383  }384 385  static void doubleLevelAccessField(const Wrapper &x, const Wrapper &y) {386    use(x.a.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}387    use(y.a.weakProp); // expected-note{{also accessed here}}388  }389};390 391 392// -----------------------393// False positives394// -----------------------395 396// Most of these would require flow-sensitive analysis to silence correctly.397 398void assignNil(Test *a) {399  if (condition())400    a.weakProp = nil; // expected-note{{also accessed here}}401 402  use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}403}404 405void branch(Test *a) {406  if (condition())407    use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}408  else409    use(a.weakProp); // expected-note{{also accessed here}}410}411 412void doubleLevelAccess(Test *a, Test *b) {413  use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}414  use(b.strongProp.weakProp); // expected-note{{also accessed here}}415 416  use(a.weakProp.weakProp); // no-warning417}418 419void doubleLevelAccessIvar(Test *a, Test *b) {420  use(a->ivar.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}421  use(b->ivar.weakProp); // expected-note{{also accessed here}}422 423  use(a.strongProp.weakProp); // no-warning424}425 426@interface X427@end428 429@implementation X430- (int) warningAboutWeakVariableInsideTypeof {431    __typeof__(self) __weak weakSelf = self;432    ^(){433        __typeof__(weakSelf) blockSelf = weakSelf;434        use(blockSelf);435    }();436    return sizeof(weakSelf);437}438@end439 440@interface NSNull441+ (NSNull *)null;442@end443 444@interface INTF @end445 446@implementation INTF447- (void) Meth : (id) data448{449  data = data ?: NSNull.null;450}451@end452 453// This used to crash in WeakObjectProfileTy::getBaseInfo when getBase() was454// called on an ObjCPropertyRefExpr object whose receiver was an interface.455 456@class NSString;457@interface NSBundle458+(NSBundle *)foo;459@property (class, strong) NSBundle *foo2;460@property (strong) NSString *prop;461@property(weak) NSString *weakProp;462@end463 464@interface NSBundle2 : NSBundle465@end466 467void foo() {468  NSString * t = NSBundle.foo.prop;469  use(NSBundle.foo.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}470  use(NSBundle2.foo.weakProp); // expected-note{{also accessed here}}471 472  NSString * t2 = NSBundle.foo2.prop;473  use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}474  use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}}475  decltype([NSBundle2.foo2 weakProp]) t3;476  decltype(NSBundle2.foo2.weakProp) t4;477  __typeof__(NSBundle2.foo2.weakProp) t5;478}479 480// This used to crash in the constructor of WeakObjectProfileTy when a481// DeclRefExpr was passed that didn't reference a VarDecl.482 483typedef INTF * INTFPtrTy;484 485enum E {486  e1487};488 489void foo1() {490  INTFPtrTy tmp = (INTFPtrTy)e1;491#if __has_feature(objc_arc)492// expected-error@-2{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}}493#endif494}495 496@class NSString;497static NSString* const kGlobal = @"";498 499@interface NSDictionary500- (id)objectForKeyedSubscript:(id)key;501@end502 503@interface WeakProp504@property (weak) NSDictionary *nd;505@end506 507@implementation WeakProp508-(void)m {509  (void)self.nd[@""]; // no warning510}511@end512