1// RUN: %clang_cc1 -verify -fsyntax-only -fblocks -fobjc-exceptions -Wcompletion-handler -Wno-pointer-to-int-cast %s 2 3#define NULL (void *)0 4#define nil (id)0 5#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 NSObject 14@end 15@interface NSObject <NSObject> 16- (instancetype)init; 17- (id)copy; 18- (id)class; 19- autorelease; 20@end 21 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@end 29@interface NSMutableArray<ObjectType> : NSArray <ObjectType> 30- addObject:anObject; 31@end 32@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-warning 75 callback(); // no-warning 76 callback(); // no-warning 77 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-warning 108} 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 situation 127 // 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-warning 150} 151 152void escaped_one_block_2(void (^callback)(void) CALLED_ONCE) { 153 escape(callback); // no-warning 154 callback(); 155} 156 157void escaped_one_path_1(int cond, void (^callback)(void) CALLED_ONCE) { 158 if (cond) { 159 escape(callback); // no-warning 160 } 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-warning 168 } 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-warning 208} 209 210void indirect_call_no_warning_1(void (^callback)(void) CALLED_ONCE) { 211 indirect_call(callback); // no-warning 212} 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-warning 221} 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 type 232 // alone when there is no actual declaration of the marked parameter. 233 meta(callback); 234 callback(); 235 // no-warning 236} 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-warning 252} 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-warning 261} 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-warning 270} 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-warning 298 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 from 330 // the first statement in the compound statement 331 (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 MAYBE 451}; 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-warning 466} 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-warning 487} 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-warning 497} 498 499void noreturn_3(int cond, void (^callback)(void) CALLED_ONCE) { 500 if (cond) { 501 exit(1); 502 } 503 504 callback(); 505 // no-warning 506} 507 508void noreturn_4(void (^callback)(void) CALLED_ONCE) { 509 exit(1); 510 // no-warning 511} 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 backward 516 // analysis. We can probably report it here, but for the sake of 517 // the simplicity of our analysis, we don't. 518 if (cond == 42) { 519 callback(); 520 } 521 exit(1); 522 } 523 callback(); 524 // no-warning 525} 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-warning 549} 550 551void call_with_check_2(void (^callback)(void) CALLED_ONCE) { 552 if (!callback) { 553 } else { 554 callback(); 555 } 556 // no-warning 557} 558 559void call_with_check_3(void (^callback)(void) CALLED_ONCE) { 560 if (callback != NULL) 561 callback(); 562 // no-warning 563} 564 565void call_with_check_4(void (^callback)(void) CALLED_ONCE) { 566 if (NULL != callback) 567 callback(); 568 // no-warning 569} 570 571void call_with_check_5(void (^callback)(void) CALLED_ONCE) { 572 if (callback == NULL) { 573 } else { 574 callback(); 575 } 576 // no-warning 577} 578 579void call_with_check_6(void (^callback)(void) CALLED_ONCE) { 580 if (NULL == callback) { 581 } else { 582 callback(); 583 } 584 // no-warning 585} 586 587int call_with_check_7(int (^callback)(void) CALLED_ONCE) { 588 return callback ? callback() : 0; 589 // no-warning 590} 591 592void call_with_builtin_check_1(int (^callback)(void) CALLED_ONCE) { 593 if (LIKELY(callback)) 594 callback(); 595 // no-warning 596} 597 598void call_with_builtin_check_2(int (^callback)(void) CALLED_ONCE) { 599 if (!UNLIKELY(callback)) { 600 } else { 601 callback(); 602 } 603 // no-warning 604} 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-warning 612} 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-warning 620} 621 622void call_with_builtin_check_5(int (^callback)(void) CALLED_ONCE) { 623 if (LIKELY_WITH_PROBA(callback, 0.9)) 624 callback(); 625 // no-warning 626} 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-warning 634} 635 636void call_with_builtin_check_7(int (^callback)(void) CALLED_ONCE) { 637 if (UNPRED(callback)) { 638 } else { 639 callback(); 640 } 641 // no-warning 642} 643 644void call_with_builtin_check_8(int (^callback)(void) CALLED_ONCE) { 645 if (LIKELY(callback != nil)) 646 callback(); 647 // no-warning 648} 649 650void call_with_builtin_check_9(int (^callback)(void) CALLED_ONCE) { 651 if (!UNLIKELY(callback == NULL)) 652 callback(); 653 // no-warning 654} 655 656void unreachable_true_branch(void (^callback)(void) CALLED_ONCE) { 657 if (0) { 658 659 } else { 660 callback(); 661 } 662 // no-warning 663} 664 665void unreachable_false_branch(void (^callback)(void) CALLED_ONCE) { 666 if (1) { 667 callback(); 668 } 669 // no-warning 670} 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-warning 687} 688 689void escape_through_assignment_1(void (^callback)(void) CALLED_ONCE) { 690 id escapee; 691 escapee = callback; 692 escape(escapee); 693 // no-warning 694} 695 696void escape_through_assignment_2(void (^callback)(void) CALLED_ONCE) { 697 id escapee = callback; 698 escape(escapee); 699 // no-warning 700} 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-warning 708} 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 future 729 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-warning 749} 750 751void suppression_2(int cond, void (^callback)(void) CALLED_ONCE) { 752 if (cond) { 753 (void)callback; // no-warning 754 } 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 should 761 // 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 : NSObject 769- (void)escape:(void (^)(void))callback; 770- (void)indirect_call:(void (^)(void))CALLED_ONCE callback; 771- (void)indirect_call_conv_1:(int)cond 772 completionHandler:(void (^)(void))completionHandler; 773- (void)indirect_call_conv_2:(int)cond 774 completionHandler:(void (^)(void))handler; 775- (void)indirect_call_conv_3WithCompletion:(void (^)(void))handler; 776- (void)indirect_call_conv_4:(void (^)(void))handler 777 __attribute__((swift_async(swift_private, 1))); 778- (void)exit:(int)code NORETURN; 779- (int)condition; 780@end 781 782@interface TestClass : TestBase 783@property(strong) NSMutableArray *handlers; 784@property(strong) id storedHandler; 785@property int wasCanceled; 786@property(getter=hasErrors) int error; 787@end 788 789@implementation TestClass 790 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-warning 850} 851 852- (void)escaped_one_path:(int)cond callback:(void (^)(void))CALLED_ONCE callback { 853 if (cond) { 854 [self escape:callback]; // no-warning 855 } else { 856 callback(); 857 } 858} 859 860- (void)block_call_1:(void (^)(void))CALLED_ONCE callback { 861 // We consider captures by blocks as escapes 862 [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)cond 879 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-warning 907} 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-warning 919} 920 921- (void)escape_through_copy:(void (^)(void))completionHandler { 922 _storedHandler = [completionHandler copy]; 923 // no-warning 924} 925 926- (void)escape_through_copy_and_autorelease:(void (^)(void))completionHandler { 927 _storedHandler = [[completionHandler copy] autorelease]; 928 // no-warning 929} 930 931- (void)complex_escape:(void (^)(void))completionHandler { 932 if (completionHandler) { 933 [_handlers addObject:[[completionHandler copy] autorelease]]; 934 } 935 // no-warning 936} 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 future 952 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 future 961 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 future 970 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 from 979 // 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-warning 994} 995 996- (void)empty_base_2:(void (^)(void))completionHandler { 997 // no-warning 998} 999 1000- (int)empty_base_3:(void (^)(void))completionHandler { 1001 return 1; 1002 // no-warning 1003} 1004 1005- (int)empty_base_4:(void (^)(void))completionHandler { 1006 NSAssert(0, @"Subclass must implement"); 1007 return 1; 1008 // no-warning 1009} 1010 1011- (int)empty_base_5:(void (^)(void))completionHandler { 1012 NSAssert(0, @"%@ doesn't support", [self class]); 1013 return 1; 1014 // no-warning 1015} 1016 1017#undef NSAssert 1018#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-warning 1027} 1028 1029#undef NSAssert 1030#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-warning 1039} 1040 1041- (void)two_conditions_1:(int)first 1042 second:(int)second 1043 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)first 1051 second:(int)second 1052 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-warning 1093 completionHandler(); 1094 } 1095} 1096 1097- (void)test_swift_async_none:(int)cond 1098 completionHandler:(void (^)(void))handler __attribute__((swift_async(none))) { 1099 if (cond) { 1100 // no-warning 1101 handler(); 1102 } 1103} 1104 1105- (void)test_swift_async_param:(int)cond 1106 callback:(void (^)(void))callback 1107 __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)cond1 1115 second:(int)cond2 1116 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)cond1 1128 second:(int)cond2 1129 completion:(void (^)(void))handler { 1130 if (cond1) { 1131 handler(); 1132 handler = nil; 1133 // no-warning 1134 } 1135 1136 if (cond2) { 1137 handler(); 1138 } 1139} 1140 1141- (void)test_nil_suppression_2:(int)cond1 1142 second:(int)cond2 1143 completion:(void (^)(void))handler { 1144 if (cond1) { 1145 handler(); 1146 handler = NULL; 1147 // no-warning 1148 } 1149 1150 if (cond2) { 1151 handler(); 1152 } 1153} 1154 1155- (void)test_nil_suppression_3:(int)cond1 1156 second:(int)cond2 1157 completion:(void (^)(void))handler { 1158 if (cond1) { 1159 handler(); 1160 handler = 0; 1161 // no-warning 1162 } 1163 1164 if (cond2) { 1165 handler(); 1166 } 1167} 1168 1169- (void)test_escape_before_branch:(int)cond 1170 withCompletion:(void (^)(void))handler { 1171 if (cond) { 1172 filler(); 1173 } 1174 1175 void (^copiedHandler)(void) = ^{ 1176 handler(); 1177 }; 1178 1179 if (cond) { 1180 // no-warning 1181 handler(); 1182 } else { 1183 copiedHandler(); 1184 } 1185} 1186 1187- (void)test_escape_after_branch:(int)cond 1188 withCompletion:(void (^)(void))handler { 1189 if (cond) { 1190 // no-warning 1191 handler(); 1192 } 1193 1194 escape(handler); 1195} 1196 1197// rdar://74441906 1198typedef void (^DeferredBlock)(void); 1199static inline void DefferedCallback(DeferredBlock *inBlock) { (*inBlock)(); } 1200#define _DEFERCONCAT(a, b) a##b 1201#define _DEFERNAME(a) _DEFERCONCAT(__DeferredVar_, a) 1202#define DEFER __extension__ __attribute__((cleanup(DefferedCallback), unused)) \ 1203 DeferredBlock _DEFERNAME(__COUNTER__) = ^ 1204 1205- (void)test_cleanup_1:(int)cond 1206 withCompletion:(void (^)(void))handler { 1207 int error = 0; 1208 DEFER { 1209 if (error) 1210 handler(); 1211 }; 1212 1213 if (cond) { 1214 error = 1; 1215 } else { 1216 // no-warning 1217 handler(); 1218 } 1219} 1220 1221- (void)test_cleanup_2:(int)cond 1222 withCompletion:(void (^)(void))handler { 1223 int error = 0; 1224 DEFER { 1225 if (error) 1226 handler(); 1227 }; 1228 1229 if (cond) { 1230 error = 1; 1231 } else { 1232 handler(); // expected-note{{previous call is here}} 1233 } 1234 1235 // We still can warn about double call even in this case. 1236 handler(); // expected-warning{{completion handler is called twice}} 1237} 1238 1239- (void)initWithAdditions:(int)cond 1240 withCompletion:(void (^)(void))handler { 1241 self = [self init]; 1242 if (self) { 1243 escape(handler); 1244 } 1245 // no-warning 1246} 1247 1248@end 1249