brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.0 KiB · f23e41e Raw
1258 lines · plain
1// RUN: %clang_cc1 -verify -fsyntax-only -fblocks -fobjc-exceptions -Wcompletion-handler -Wno-pointer-to-int-cast %s2 3#define NULL (void *)04#define nil (id)05#define CALLED_ONCE __attribute__((called_once))6#define NORETURN __attribute__((noreturn))7#define LIKELY(X) __builtin_expect(!!(X), 1)8#define UNLIKELY(X) __builtin_expect(!!(X), 0)9#define LIKELY_WITH_PROBA(X, P) __builtin_expect_with_probability(!!(X), 1, P)10#define UNLIKELY_WITH_PROBA(X, P) __builtin_expect_with_probability(!!(X), 0, P)11#define UNPRED(X) __builtin_unpredictable((long)(X))12 13@protocol NSObject14@end15@interface NSObject <NSObject>16- (instancetype)init;17- (id)copy;18- (id)class;19- autorelease;20@end21 22typedef unsigned int NSUInteger;23typedef struct {24} NSFastEnumerationState;25 26@interface NSArray <__covariant NSFastEnumeration>27- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;28@end29@interface NSMutableArray<ObjectType> : NSArray <ObjectType>30- addObject:anObject;31@end32@class NSString, Protocol;33extern void NSLog(NSString *format, ...);34 35typedef int group_t;36typedef struct dispatch_queue_s *dispatch_queue_t;37typedef void (^dispatch_block_t)(void);38extern dispatch_queue_t queue;39 40void dispatch_group_async(dispatch_queue_t queue,41                          group_t group,42                          dispatch_block_t block);43void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);44 45void escape(void (^callback)(void));46void escape_void(void *);47void indirect_call(void (^callback)(void) CALLED_ONCE);48void indirect_conv(void (^completionHandler)(void));49void filler(void);50void exit(int) NORETURN;51 52void double_call_one_block(void (^callback)(void) CALLED_ONCE) {53  callback(); // expected-note{{previous call is here}}54  callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}55}56 57void double_call_one_block_parens(void (^callback)(void) CALLED_ONCE) {58  (callback)(); // expected-note{{previous call is here}}59  (callback)(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}60}61 62void double_call_one_block_ptr(void (*callback)(void) CALLED_ONCE) {63  callback(); // expected-note{{previous call is here}}64  callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}65}66 67void double_call_one_block_ptr_deref(void (*callback)(void) CALLED_ONCE) {68  (*callback)(); // expected-note{{previous call is here}}69  (*callback)(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}70}71 72void multiple_call_one_block(void (^callback)(void) CALLED_ONCE) {73  // We don't really need to repeat the same warning for the same parameter.74  callback(); // no-warning75  callback(); // no-warning76  callback(); // no-warning77  callback(); // expected-note{{previous call is here}}78  callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}79}80 81void double_call_branching_1(int cond, void (^callback)(void) CALLED_ONCE) {82  if (cond) {83    callback(); // expected-note{{previous call is here}}84  } else {85    cond += 42;86  }87  callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}88}89 90void double_call_branching_2(int cond, void (^callback)(void) CALLED_ONCE) {91  callback();92  // expected-note@-1{{previous call is here; set to nil to indicate it cannot be called afterwards}}93 94  if (cond) {95    callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}96  } else {97    cond += 42;98  }99}100 101void double_call_branching_3(int cond, void (^callback)(void) CALLED_ONCE) {102  if (cond) {103    callback();104  } else {105    callback();106  }107  // no-warning108}109 110void double_call_branching_4(int cond1, int cond2, void (^callback)(void) CALLED_ONCE) {111  if (cond1) {112    cond2 = !cond2;113  } else {114    callback();115    // expected-note@-1{{previous call is here; set to nil to indicate it cannot be called afterwards}}116  }117 118  if (cond2) {119    callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}120  }121}122 123void double_call_loop(int counter, void (^callback)(void) CALLED_ONCE) {124  while (counter > 0) {125    counter--;126    // Both note and warning are on the same line, which is a common situation127    // in loops.128    callback(); // expected-note{{previous call is here}}129    // expected-warning@-1{{'callback' parameter marked 'called_once' is called twice}}130  }131}132 133void never_called_trivial(void (^callback)(void) CALLED_ONCE) {134  // expected-warning@-1{{'callback' parameter marked 'called_once' is never called}}135}136 137int never_called_branching(int x, void (^callback)(void) CALLED_ONCE) {138  // expected-warning@-1{{'callback' parameter marked 'called_once' is never called}}139  x -= 42;140 141  if (x == 10) {142    return 0;143  }144 145  return x + 15;146}147 148void escaped_one_block_1(void (^callback)(void) CALLED_ONCE) {149  escape(callback); // no-warning150}151 152void escaped_one_block_2(void (^callback)(void) CALLED_ONCE) {153  escape(callback); // no-warning154  callback();155}156 157void escaped_one_path_1(int cond, void (^callback)(void) CALLED_ONCE) {158  if (cond) {159    escape(callback); // no-warning160  } else {161    callback();162  }163}164 165void escaped_one_path_2(int cond, void (^callback)(void) CALLED_ONCE) {166  if (cond) {167    escape(callback); // no-warning168  }169 170  callback();171}172 173void escaped_one_path_3(int cond, void (^callback)(void) CALLED_ONCE) {174  if (cond) {175    // expected-warning@-1{{'callback' parameter marked 'called_once' is never used when taking false branch}}176    escape(callback);177  }178}179 180void escape_in_between_1(void (^callback)(void) CALLED_ONCE) {181  callback(); // expected-note{{previous call is here}}182  escape(callback);183  callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}184}185 186void escape_in_between_2(int cond, void (^callback)(void) CALLED_ONCE) {187  callback(); // expected-note{{previous call is here}}188  if (cond) {189    escape(callback);190  }191  callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}192}193 194void escape_in_between_3(int cond, void (^callback)(void) CALLED_ONCE) {195  callback(); // expected-note{{previous call is here}}196 197  if (cond) {198    escape(callback);199  } else {200    escape_void((__bridge void *)callback);201  }202 203  callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}204}205 206void escaped_as_void_ptr(void (^callback)(void) CALLED_ONCE) {207  escape_void((__bridge void *)callback); // no-warning208}209 210void indirect_call_no_warning_1(void (^callback)(void) CALLED_ONCE) {211  indirect_call(callback); // no-warning212}213 214void indirect_call_no_warning_2(int cond, void (^callback)(void) CALLED_ONCE) {215  if (cond) {216    indirect_call(callback);217  } else {218    callback();219  }220  // no-warning221}222 223void indirect_call_double_call(void (^callback)(void) CALLED_ONCE) {224  indirect_call(callback); // expected-note{{previous call is here}}225  callback();              // expected-warning{{'callback' parameter marked 'called_once' is called twice}}226}227 228void indirect_call_within_direct_call(void (^callback)(void) CALLED_ONCE,229                                      void (^meta)(void (^param)(void) CALLED_ONCE) CALLED_ONCE) {230  // TODO: Report warning for 'callback'.231  //       At the moment, it is not possible to access 'called_once' attribute from the type232  //       alone when there is no actual declaration of the marked parameter.233  meta(callback);234  callback();235  // no-warning236}237 238void block_call_1(void (^callback)(void) CALLED_ONCE) {239  indirect_call( // expected-note{{previous call is here}}240      ^{241        callback();242      });243  callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}244}245 246void block_call_2(void (^callback)(void) CALLED_ONCE) {247  escape(^{248    callback();249  });250  callback();251  // no-warning252}253 254void block_call_3(int cond, void (^callback)(void) CALLED_ONCE) {255  ^{256    if (cond) {257      callback(); // expected-note{{previous call is here}}258    }259    callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}260  }();          // no-warning261}262 263void block_call_4(int cond, void (^callback)(void) CALLED_ONCE) {264  ^{265    if (cond) {266      // expected-warning@-1{{'callback' parameter marked 'called_once' is never used when taking false branch}}267      escape(callback);268    }269  }(); // no-warning270}271 272void block_call_5(void (^outer)(void) CALLED_ONCE) {273  ^(void (^inner)(void) CALLED_ONCE) {274    // expected-warning@-1{{'inner' parameter marked 'called_once' is never called}}275  }(outer);276}277 278void block_with_called_once(void (^outer)(void) CALLED_ONCE) {279  escape_void((__bridge void *)^(void (^inner)(void) CALLED_ONCE) {280    inner(); // expected-note{{previous call is here}}281    inner(); // expected-warning{{'inner' parameter marked 'called_once' is called twice}}282  });283  outer(); // expected-note{{previous call is here}}284  outer(); // expected-warning{{'outer' parameter marked 'called_once' is called twice}}285}286 287void block_dispatch_call(int cond, void (^callback)(void) CALLED_ONCE) {288  dispatch_async(queue, ^{289    if (cond) // expected-warning{{'callback' parameter marked 'called_once' is never called when taking false branch}}290      callback();291  });292}293 294void block_escape_call_1(int cond, void (^callback)(void) CALLED_ONCE) {295  escape_void((__bridge void *)^{296    if (cond) {297      // no-warning298      callback();299    }300  });301}302 303void block_escape_call_2(int cond, void (^callback)(void) CALLED_ONCE) {304  escape_void((__bridge void *)^{305    if (cond) {306      callback(); // expected-note{{previous call is here}}307    }308    // Double call can still be reported.309    callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}310  });311}312 313void never_called_one_exit(int cond, void (^callback)(void) CALLED_ONCE) {314  if (!cond) // expected-warning{{'callback' parameter marked 'called_once' is never called when taking true branch}}315    return;316 317  callback();318}319 320void never_called_if_then_1(int cond, void (^callback)(void) CALLED_ONCE) {321  if (cond) { // expected-warning{{'callback' parameter marked 'called_once' is never called when taking true branch}}322  } else {323    callback();324  }325}326 327void never_called_if_then_2(int cond, void (^callback)(void) CALLED_ONCE) {328  if (cond) { // expected-warning{{'callback' parameter marked 'called_once' is never called when taking true branch}}329    // This way the first statement in the basic block is different from330    // the first statement in the compound statement331    (void)cond;332  } else {333    callback();334  }335}336 337void never_called_if_else_1(int cond, void (^callback)(void) CALLED_ONCE) {338  if (cond) { // expected-warning{{'callback' parameter marked 'called_once' is never called when taking false branch}}339    callback();340  } else {341  }342}343 344void never_called_if_else_2(int cond, void (^callback)(void) CALLED_ONCE) {345  if (cond) { // expected-warning{{'callback' parameter marked 'called_once' is never called when taking false branch}}346    callback();347  }348}349 350void never_called_two_ifs(int cond1, int cond2, void (^callback)(void) CALLED_ONCE) {351  if (cond1) {   // expected-warning{{'callback' parameter marked 'called_once' is never called when taking false branch}}352    if (cond2) { // expected-warning{{'callback' parameter marked 'called_once' is never called when taking true branch}}353      return;354    }355    callback();356  }357}358 359void never_called_ternary_then(int cond, void (^other)(void), void (^callback)(void) CALLED_ONCE) {360  return cond ? // expected-warning{{'callback' parameter marked 'called_once' is never called when taking true branch}}361             other()362              : callback();363}364 365void never_called_for_false(int size, void (^callback)(void) CALLED_ONCE) {366  for (int i = 0; i < size; ++i) {367    // expected-warning@-1{{'callback' parameter marked 'called_once' is never called when skipping the loop}}368    callback();369    break;370  }371}372 373void never_called_for_true(int size, void (^callback)(void) CALLED_ONCE) {374  for (int i = 0; i < size; ++i) {375    // expected-warning@-1{{'callback' parameter marked 'called_once' is never called when entering the loop}}376    return;377  }378  callback();379}380 381void never_called_while_false(int cond, void (^callback)(void) CALLED_ONCE) {382  while (cond) { // expected-warning{{'callback' parameter marked 'called_once' is never called when skipping the loop}}383    callback();384    break;385  }386}387 388void never_called_while_true(int cond, void (^callback)(void) CALLED_ONCE) {389  while (cond) { // expected-warning{{'callback' parameter marked 'called_once' is never called when entering the loop}}390    return;391  }392  callback();393}394 395void never_called_switch_case(int cond, void (^callback)(void) CALLED_ONCE) {396  switch (cond) {397  case 1:398    callback();399    break;400  case 2:401    callback();402    break;403  case 3: // expected-warning{{'callback' parameter marked 'called_once' is never called when handling this case}}404    break;405  default:406    callback();407    break;408  }409}410 411void never_called_switch_default(int cond, void (^callback)(void) CALLED_ONCE) {412  switch (cond) {413  case 1:414    callback();415    break;416  case 2:417    callback();418    break;419  default: // expected-warning{{'callback' parameter marked 'called_once' is never called when handling this case}}420    break;421  }422}423 424void never_called_switch_two_cases(int cond, void (^callback)(void) CALLED_ONCE) {425  switch (cond) {426  case 1: // expected-warning{{'callback' parameter marked 'called_once' is never called when handling this case}}427    break;428  case 2: // expected-warning{{'callback' parameter marked 'called_once' is never called when handling this case}}429    break;430  default:431    callback();432    break;433  }434}435 436void never_called_switch_none(int cond, void (^callback)(void) CALLED_ONCE) {437  switch (cond) { // expected-warning{{'callback' parameter marked 'called_once' is never called when none of the cases applies}}438  case 1:439    callback();440    break;441  case 2:442    callback();443    break;444  }445}446 447enum YesNoOrMaybe {448  YES,449  NO,450  MAYBE451};452 453void exhaustive_switch(enum YesNoOrMaybe cond, void (^callback)(void) CALLED_ONCE) {454  switch (cond) {455  case YES:456    callback();457    break;458  case NO:459    callback();460    break;461  case MAYBE:462    callback();463    break;464  }465  // no-warning466}467 468void called_twice_exceptions(void (^callback)(void) CALLED_ONCE) {469  // TODO: Obj-C exceptions are not supported in CFG,470  //       we should report warnings in these as well.471  @try {472    callback();473    callback();474  }475  @finally {476    callback();477  }478}479 480void noreturn_1(int cond, void (^callback)(void) CALLED_ONCE) {481  if (cond) {482    exit(1);483  } else {484    callback();485  }486  // no-warning487}488 489void noreturn_2(int cond, void (^callback)(void) CALLED_ONCE) {490  if (cond) {491    callback();492    exit(1);493  } else {494    callback();495  }496  // no-warning497}498 499void noreturn_3(int cond, void (^callback)(void) CALLED_ONCE) {500  if (cond) {501    exit(1);502  }503 504  callback();505  // no-warning506}507 508void noreturn_4(void (^callback)(void) CALLED_ONCE) {509  exit(1);510  // no-warning511}512 513void noreturn_5(int cond, void (^callback)(void) CALLED_ONCE) {514  if (cond) {515    // NOTE: This is an ambiguous case caused by the fact that we do a backward516    //       analysis.  We can probably report it here, but for the sake of517    //       the simplicity of our analysis, we don't.518    if (cond == 42) {519      callback();520    }521    exit(1);522  }523  callback();524  // no-warning525}526 527void never_called_noreturn_1(int cond, void (^callback)(void) CALLED_ONCE) {528  // expected-warning@-1{{'callback' parameter marked 'called_once' is never called}}529  if (cond) {530    exit(1);531  }532}533 534void double_call_noreturn(int cond, void (^callback)(void) CALLED_ONCE) {535  callback(); // expected-note{{previous call is here}}536 537  if (cond) {538    if (cond == 42) {539      callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}540    }541    exit(1);542  }543}544 545void call_with_check_1(void (^callback)(void) CALLED_ONCE) {546  if (callback)547    callback();548  // no-warning549}550 551void call_with_check_2(void (^callback)(void) CALLED_ONCE) {552  if (!callback) {553  } else {554    callback();555  }556  // no-warning557}558 559void call_with_check_3(void (^callback)(void) CALLED_ONCE) {560  if (callback != NULL)561    callback();562  // no-warning563}564 565void call_with_check_4(void (^callback)(void) CALLED_ONCE) {566  if (NULL != callback)567    callback();568  // no-warning569}570 571void call_with_check_5(void (^callback)(void) CALLED_ONCE) {572  if (callback == NULL) {573  } else {574    callback();575  }576  // no-warning577}578 579void call_with_check_6(void (^callback)(void) CALLED_ONCE) {580  if (NULL == callback) {581  } else {582    callback();583  }584  // no-warning585}586 587int call_with_check_7(int (^callback)(void) CALLED_ONCE) {588  return callback ? callback() : 0;589  // no-warning590}591 592void call_with_builtin_check_1(int (^callback)(void) CALLED_ONCE) {593  if (LIKELY(callback))594    callback();595  // no-warning596}597 598void call_with_builtin_check_2(int (^callback)(void) CALLED_ONCE) {599  if (!UNLIKELY(callback)) {600  } else {601    callback();602  }603  // no-warning604}605 606void call_with_builtin_check_3(int (^callback)(void) CALLED_ONCE) {607  if (__builtin_expect((long)callback, 0L)) {608  } else {609    callback();610  }611  // no-warning612}613 614void call_with_builtin_check_4(int (^callback)(void) CALLED_ONCE) {615  if (__builtin_expect(0L, (long)callback)) {616  } else {617    callback();618  }619  // no-warning620}621 622void call_with_builtin_check_5(int (^callback)(void) CALLED_ONCE) {623  if (LIKELY_WITH_PROBA(callback, 0.9))624    callback();625  // no-warning626}627 628void call_with_builtin_check_6(int (^callback)(void) CALLED_ONCE) {629  if (!UNLIKELY_WITH_PROBA(callback, 0.9)) {630  } else {631    callback();632  }633  // no-warning634}635 636void call_with_builtin_check_7(int (^callback)(void) CALLED_ONCE) {637  if (UNPRED(callback)) {638  } else {639    callback();640  }641  // no-warning642}643 644void call_with_builtin_check_8(int (^callback)(void) CALLED_ONCE) {645  if (LIKELY(callback != nil))646    callback();647  // no-warning648}649 650void call_with_builtin_check_9(int (^callback)(void) CALLED_ONCE) {651  if (!UNLIKELY(callback == NULL))652    callback();653  // no-warning654}655 656void unreachable_true_branch(void (^callback)(void) CALLED_ONCE) {657  if (0) {658 659  } else {660    callback();661  }662  // no-warning663}664 665void unreachable_false_branch(void (^callback)(void) CALLED_ONCE) {666  if (1) {667    callback();668  }669  // no-warning670}671 672void never_called_conv_1(void (^completionHandler)(void)) {673  // expected-warning@-1{{completion handler is never called}}674}675 676void never_called_conv_2(void (^completion)(void)) {677  // expected-warning@-1{{completion handler is never called}}678}679 680void never_called_conv_WithCompletion(void (^callback)(void)) {681  // expected-warning@-1{{completion handler is never called}}682}683 684void indirectly_called_conv(void (^completionHandler)(void)) {685  indirect_conv(completionHandler);686  // no-warning687}688 689void escape_through_assignment_1(void (^callback)(void) CALLED_ONCE) {690  id escapee;691  escapee = callback;692  escape(escapee);693  // no-warning694}695 696void escape_through_assignment_2(void (^callback)(void) CALLED_ONCE) {697  id escapee = callback;698  escape(escapee);699  // no-warning700}701 702void escape_through_assignment_3(void (^callback1)(void) CALLED_ONCE,703                                 void (^callback2)(void) CALLED_ONCE) {704  id escapee1 = callback1, escapee2 = callback2;705  escape(escapee1);706  escape(escapee2);707  // no-warning708}709 710void not_called_in_throw_branch_1(id exception, void (^callback)(void) CALLED_ONCE) {711  if (exception) {712    @throw exception;713  }714 715  callback();716}717 718void not_called_in_throw_branch_2(id exception, void (^callback)(void) CALLED_ONCE) {719  // expected-warning@-1{{'callback' parameter marked 'called_once' is never called}}720  if (exception) {721    @throw exception;722  }723}724 725void conventional_error_path_1(int error, void (^completionHandler)(void)) {726  if (error) {727    // expected-warning@-1{{completion handler is never called when taking true branch}}728    // This behavior might be tweaked in the future729    return;730  }731 732  completionHandler();733}734 735void conventional_error_path_2(int error, void (^callback)(void) CALLED_ONCE) {736  // Conventions do not apply to explicitly marked parameters.737  if (error) {738    // expected-warning@-1{{'callback' parameter marked 'called_once' is never called when taking true branch}}739    return;740  }741 742  callback();743}744 745void suppression_1(void (^callback)(void) CALLED_ONCE) {746  // This is a way to tell the analysis that we know about this path,747  // and we do not want to call the callback here.748  (void)callback; // no-warning749}750 751void suppression_2(int cond, void (^callback)(void) CALLED_ONCE) {752  if (cond) {753    (void)callback; // no-warning754  } else {755    callback();756  }757}758 759void suppression_3(int cond, void (^callback)(void) CALLED_ONCE) {760  // Even if we do this on one of the paths, it doesn't mean we should761  // forget about other paths.762  if (cond) {763    // expected-warning@-1{{'callback' parameter marked 'called_once' is never used when taking false branch}}764    (void)callback;765  }766}767 768@interface TestBase : NSObject769- (void)escape:(void (^)(void))callback;770- (void)indirect_call:(void (^)(void))CALLED_ONCE callback;771- (void)indirect_call_conv_1:(int)cond772           completionHandler:(void (^)(void))completionHandler;773- (void)indirect_call_conv_2:(int)cond774           completionHandler:(void (^)(void))handler;775- (void)indirect_call_conv_3WithCompletion:(void (^)(void))handler;776- (void)indirect_call_conv_4:(void (^)(void))handler777    __attribute__((swift_async(swift_private, 1)));778- (void)exit:(int)code NORETURN;779- (int)condition;780@end781 782@interface TestClass : TestBase783@property(strong) NSMutableArray *handlers;784@property(strong) id storedHandler;785@property int wasCanceled;786@property(getter=hasErrors) int error;787@end788 789@implementation TestClass790 791- (void)double_indirect_call_1:(void (^)(void))CALLED_ONCE callback {792  [self indirect_call:callback]; // expected-note{{previous call is here}}793  [self indirect_call:callback]; // expected-warning{{'callback' parameter marked 'called_once' is called twice}}794}795 796- (void)double_indirect_call_2:(void (^)(void))CALLED_ONCE callback {797  [self indirect_call_conv_1:0 // expected-note{{previous call is here}}798           completionHandler:callback];799  [self indirect_call_conv_1:1 // expected-warning{{'callback' parameter marked 'called_once' is called twice}}800           completionHandler:callback];801}802 803- (void)double_indirect_call_3:(void (^)(void))completionHandler {804  [self indirect_call_conv_2:0 // expected-note{{previous call is here}}805           completionHandler:completionHandler];806  [self indirect_call_conv_2:1 // expected-warning{{completion handler is called twice}}807           completionHandler:completionHandler];808}809 810- (void)double_indirect_call_4:(void (^)(void))completion {811  [self indirect_call_conv_2:0 // expected-note{{previous call is here}}812           completionHandler:completion];813  [self indirect_call_conv_2:1 // expected-warning{{completion handler is called twice}}814           completionHandler:completion];815}816 817- (void)double_indirect_call_5:(void (^)(void))withCompletionHandler {818  [self indirect_call_conv_2:0 // expected-note{{previous call is here}}819           completionHandler:withCompletionHandler];820  [self indirect_call_conv_2:1 // expected-warning{{completion handler is called twice}}821           completionHandler:withCompletionHandler];822}823 824- (void)double_indirect_call_6:(void (^)(void))completionHandler {825  [self indirect_call_conv_3WithCompletion: // expected-note{{previous call is here}}826            completionHandler];827  [self indirect_call_conv_3WithCompletion: // expected-warning{{completion handler is called twice}}828            completionHandler];829}830 831- (void)double_indirect_call_7:(void (^)(void))completionHandler {832  [self indirect_call_conv_4: // expected-note{{previous call is here}}833            completionHandler];834  [self indirect_call_conv_4: // expected-warning{{completion handler is called twice}}835            completionHandler];836}837 838- (void)never_called_trivial:(void (^)(void))CALLED_ONCE callback {839  // expected-warning@-1{{'callback' parameter marked 'called_once' is never called}}840  filler();841}842 843- (void)noreturn:(int)cond callback:(void (^)(void))CALLED_ONCE callback {844  if (cond) {845    [self exit:1];846  }847 848  callback();849  // no-warning850}851 852- (void)escaped_one_path:(int)cond callback:(void (^)(void))CALLED_ONCE callback {853  if (cond) {854    [self escape:callback]; // no-warning855  } else {856    callback();857  }858}859 860- (void)block_call_1:(void (^)(void))CALLED_ONCE callback {861  // We consider captures by blocks as escapes862  [self indirect_call:(^{ // expected-note{{previous call is here}}863          callback();864        })];865  callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}866}867 868- (void)block_call_2:(int)cond callback:(void (^)(void))CALLED_ONCE callback {869  [self indirect_call:870            ^{871              if (cond) {872                // expected-warning@-1{{'callback' parameter marked 'called_once' is never used when taking false branch}}873                [self escape:callback];874              }875            }];876}877 878- (void)block_call_3:(int)cond879    completionHandler:(void (^)(void))callback {880  [self indirect_call:881            ^{882              if (cond) {883                // expected-warning@-1{{completion handler is never used when taking false branch}}884                [self escape:callback];885              }886            }];887}888 889- (void)block_call_4WithCompletion:(void (^)(void))callback {890  [self indirect_call:891            ^{892              if ([self condition]) {893                // expected-warning@-1{{completion handler is never used when taking false branch}}894                [self escape:callback];895              }896            }];897}898 899- (void)never_called_conv:(void (^)(void))completionHandler {900  // expected-warning@-1{{completion handler is never called}}901  filler();902}903 904- (void)indirectly_called_conv:(void (^)(void))completionHandler {905  indirect_conv(completionHandler);906  // no-warning907}908 909- (void)never_called_one_exit_conv:(int)cond completionHandler:(void (^)(void))handler {910  if (!cond) // expected-warning{{completion handler is never called when taking true branch}}911    return;912 913  handler();914}915 916- (void)escape_through_assignment:(void (^)(void))completionHandler {917  _storedHandler = completionHandler;918  // no-warning919}920 921- (void)escape_through_copy:(void (^)(void))completionHandler {922  _storedHandler = [completionHandler copy];923  // no-warning924}925 926- (void)escape_through_copy_and_autorelease:(void (^)(void))completionHandler {927  _storedHandler = [[completionHandler copy] autorelease];928  // no-warning929}930 931- (void)complex_escape:(void (^)(void))completionHandler {932  if (completionHandler) {933    [_handlers addObject:[[completionHandler copy] autorelease]];934  }935  // no-warning936}937 938- (void)test_crash:(void (^)(void))completionHandler cond:(int)cond {939  if (cond) {940    // expected-warning@-1{{completion handler is never used when taking false branch}}941    for (id _ in _handlers) {942    }943 944    [_handlers addObject:completionHandler];945  }946}947 948- (void)conventional_error_path_1:(void (^)(void))completionHandler {949  if (self.wasCanceled)950    // expected-warning@-1{{completion handler is never called when taking true branch}}951    // This behavior might be tweaked in the future952    return;953 954  completionHandler();955}956 957- (void)conventional_error_path_2:(void (^)(void))completionHandler {958  if (self.wasCanceled)959    // expected-warning@-1{{completion handler is never used when taking true branch}}960    // This behavior might be tweaked in the future961    return;962 963  [_handlers addObject:completionHandler];964}965 966- (void)conventional_error_path_3:(void (^)(void))completionHandler {967  if (self.hasErrors)968    // expected-warning@-1{{completion handler is never called when taking true branch}}969    // This behavior might be tweaked in the future970    return;971 972  completionHandler();973}974 975- (void)conventional_error_path_3:(int)cond completionHandler:(void (^)(void))handler {976  if (self.wasCanceled)977    // expected-warning@-1{{completion handler is never called when taking true branch}}978    // TODO: When we have an error on some other path, in order not to prevent it from979    //       being reported, we report this one as well.980    //       Probably, we should address this at some point.981    return;982 983  if (cond) {984    // expected-warning@-1{{completion handler is never called when taking false branch}}985    handler();986  }987}988 989#define NSAssert(condition, desc, ...) NSLog(desc, ##__VA_ARGS__);990 991- (void)empty_base_1:(void (^)(void))completionHandler {992  NSAssert(0, @"Subclass must implement");993  // no-warning994}995 996- (void)empty_base_2:(void (^)(void))completionHandler {997  // no-warning998}999 1000- (int)empty_base_3:(void (^)(void))completionHandler {1001  return 1;1002  // no-warning1003}1004 1005- (int)empty_base_4:(void (^)(void))completionHandler {1006  NSAssert(0, @"Subclass must implement");1007  return 1;1008  // no-warning1009}1010 1011- (int)empty_base_5:(void (^)(void))completionHandler {1012  NSAssert(0, @"%@ doesn't support", [self class]);1013  return 1;1014  // no-warning1015}1016 1017#undef NSAssert1018#define NSAssert(condition, desc, ...) \1019  if (!(condition)) {                  \1020    NSLog(desc, ##__VA_ARGS__);        \1021  }1022 1023- (int)empty_base_6:(void (^)(void))completionHandler {1024  NSAssert(0, @"%@ doesn't support", [self class]);1025  return 1;1026  // no-warning1027}1028 1029#undef NSAssert1030#define NSAssert(condition, desc, ...) \1031  do {                                 \1032    NSLog(desc, ##__VA_ARGS__);        \1033  } while (0)1034 1035- (int)empty_base_7:(void (^)(void))completionHandler {1036  NSAssert(0, @"%@ doesn't support", [self class]);1037  return 1;1038  // no-warning1039}1040 1041- (void)two_conditions_1:(int)first1042                  second:(int)second1043       completionHandler:(void (^)(void))completionHandler {1044  if (first && second) {1045    // expected-warning@-1{{completion handler is never called when taking false branch}}1046    completionHandler();1047  }1048}1049 1050- (void)two_conditions_2:(int)first1051                  second:(int)second1052       completionHandler:(void (^)(void))completionHandler {1053  if (first || second) {1054    // expected-warning@-1{{completion handler is never called when taking true branch}}1055    return;1056  }1057 1058  completionHandler();1059}1060 1061- (void)testWithCompletionHandler:(void (^)(void))callback {1062  if ([self condition]) {1063    // expected-warning@-1{{completion handler is never called when taking false branch}}1064    callback();1065  }1066}1067 1068- (void)testWithCompletion:(void (^)(void))callback {1069  if ([self condition]) {1070    // expected-warning@-1{{completion handler is never called when taking false branch}}1071    callback();1072  }1073}1074 1075- (void)test:(int)cond fooWithReplyTo:(void (^)(void))handler {1076  if (cond) {1077    // expected-warning@-1{{completion handler is never called when taking false branch}}1078    handler();1079  }1080}1081 1082- (void)test:(int)cond with:(void (^)(void))fooWithCompletionBlock {1083  if (cond) {1084    // expected-warning@-1{{completion handler is never called when taking false branch}}1085    fooWithCompletionBlock();1086  }1087}1088 1089- (void)completion_handler_wrong_type:(int (^)(void))completionHandler {1090  // We don't want to consider completion handlers with non-void return types.1091  if ([self condition]) {1092    // no-warning1093    completionHandler();1094  }1095}1096 1097- (void)test_swift_async_none:(int)cond1098            completionHandler:(void (^)(void))handler __attribute__((swift_async(none))) {1099  if (cond) {1100    // no-warning1101    handler();1102  }1103}1104 1105- (void)test_swift_async_param:(int)cond1106                      callback:(void (^)(void))callback1107    __attribute__((swift_async(swift_private, 2))) {1108  if (cond) {1109    // expected-warning@-1{{completion handler is never called when taking false branch}}1110    callback();1111  }1112}1113 1114- (void)test_nil_suggestion:(int)cond11115                     second:(int)cond21116                 completion:(void (^)(void))handler {1117  if (cond1) {1118    handler();1119    // expected-note@-1{{previous call is here; set to nil to indicate it cannot be called afterwards}}1120  }1121 1122  if (cond2) {1123    handler(); // expected-warning{{completion handler is called twice}}1124  }1125}1126 1127- (void)test_nil_suppression_1:(int)cond11128                        second:(int)cond21129                    completion:(void (^)(void))handler {1130  if (cond1) {1131    handler();1132    handler = nil;1133    // no-warning1134  }1135 1136  if (cond2) {1137    handler();1138  }1139}1140 1141- (void)test_nil_suppression_2:(int)cond11142                        second:(int)cond21143                    completion:(void (^)(void))handler {1144  if (cond1) {1145    handler();1146    handler = NULL;1147    // no-warning1148  }1149 1150  if (cond2) {1151    handler();1152  }1153}1154 1155- (void)test_nil_suppression_3:(int)cond11156                        second:(int)cond21157                    completion:(void (^)(void))handler {1158  if (cond1) {1159    handler();1160    handler = 0;1161    // no-warning1162  }1163 1164  if (cond2) {1165    handler();1166  }1167}1168 1169- (void)test_escape_before_branch:(int)cond1170                   withCompletion:(void (^)(void))handler {1171  if (cond) {1172    filler();1173  }1174 1175  void (^copiedHandler)(void) = ^{1176    handler();1177  };1178 1179  if (cond) {1180    // no-warning1181    handler();1182  } else {1183    copiedHandler();1184  }1185}1186 1187- (void)test_escape_after_branch:(int)cond1188                  withCompletion:(void (^)(void))handler {1189  if (cond) {1190    // no-warning1191    handler();1192  }1193 1194  escape(handler);1195}1196 1197- (void)test_termination:(int)cond1198                  withCompletion:(void (^)(void))handler {1199  // The code below was able to cause non-termination but should be1200  // fixed now:1201  do {1202    escape(handler);    1203    handler();    // expected-warning{{completion handler is called twice}} expected-note{{previous call is here; set to nil to indicate it cannot be called afterwards}}1204  } while (cond);1205}1206 1207typedef void (^DeferredBlock)(void);1208static inline void DefferedCallback(DeferredBlock *inBlock) { (*inBlock)(); }1209#define _DEFERCONCAT(a, b) a##b1210#define _DEFERNAME(a) _DEFERCONCAT(__DeferredVar_, a)1211#define DEFER __extension__ __attribute__((cleanup(DefferedCallback), unused)) \1212                  DeferredBlock _DEFERNAME(__COUNTER__) = ^1213 1214- (void)test_cleanup_1:(int)cond1215        withCompletion:(void (^)(void))handler {1216  int error = 0;1217  DEFER {1218    if (error)1219      handler();1220  };1221 1222  if (cond) {1223    error = 1;1224  } else {1225    // no-warning1226    handler();1227  }1228}1229 1230- (void)test_cleanup_2:(int)cond1231        withCompletion:(void (^)(void))handler {1232  int error = 0;1233  DEFER {1234    if (error)1235      handler();1236  };1237 1238  if (cond) {1239    error = 1;1240  } else {1241    handler(); // expected-note{{previous call is here}}1242  }1243 1244  // We still can warn about double call even in this case.1245  handler(); // expected-warning{{completion handler is called twice}}1246}1247 1248- (void)initWithAdditions:(int)cond1249           withCompletion:(void (^)(void))handler {1250  self = [self init];1251  if (self) {1252    escape(handler);1253  }1254  // no-warning1255}1256 1257@end1258