1 // RUN: %clang_cc1 -verify -fsyntax-only -fblocks -fobjc-exceptions -Wcompletion-handler -Wno-pointer-to-int-cast %s
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))
15 @interface NSObject <NSObject>
22 typedef unsigned int NSUInteger;
24 } NSFastEnumerationState;
26 @interface NSArray <__covariant NSFastEnumeration>
27 - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
29 @interface NSMutableArray<ObjectType> : NSArray <ObjectType>
32 @class NSString, Protocol;
33 extern void NSLog(NSString *format, ...);
36 typedef struct dispatch_queue_s *dispatch_queue_t;
37 typedef void (^dispatch_block_t)(void);
38 extern dispatch_queue_t queue;
40 void dispatch_group_async(dispatch_queue_t queue,
42 dispatch_block_t block);
43 void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
45 void escape(void (^callback)(void));
46 void escape_void(void *);
47 void indirect_call(void (^callback)(void) CALLED_ONCE);
48 void indirect_conv(void (^completionHandler)(void));
50 void exit(int) NORETURN;
52 void 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}}
57 void 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}}
62 void 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}}
67 void 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}}
72 void 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}}
81 void double_call_branching_1(int cond, void (^callback)(void) CALLED_ONCE) {
83 callback(); // expected-note{{previous call is here}}
87 callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}
90 void double_call_branching_2(int cond, void (^callback)(void) CALLED_ONCE) {
92 // expected-note@-1{{previous call is here; set to nil to indicate it cannot be called afterwards}}
95 callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}
101 void double_call_branching_3(int cond, void (^callback)(void) CALLED_ONCE) {
110 void double_call_branching_4(int cond1, int cond2, void (^callback)(void) CALLED_ONCE) {
115 // expected-note@-1{{previous call is here; set to nil to indicate it cannot be called afterwards}}
119 callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}
123 void double_call_loop(int counter, void (^callback)(void) CALLED_ONCE) {
124 while (counter > 0) {
126 // Both note and warning are on the same line, which is a common situation
128 callback(); // expected-note{{previous call is here}}
129 // expected-warning@-1{{'callback' parameter marked 'called_once' is called twice}}
133 void never_called_trivial(void (^callback)(void) CALLED_ONCE) {
134 // expected-warning@-1{{'callback' parameter marked 'called_once' is never called}}
137 int never_called_branching(int x, void (^callback)(void) CALLED_ONCE) {
138 // expected-warning@-1{{'callback' parameter marked 'called_once' is never called}}
148 void escaped_one_block_1(void (^callback)(void) CALLED_ONCE) {
149 escape(callback); // no-warning
152 void escaped_one_block_2(void (^callback)(void) CALLED_ONCE) {
153 escape(callback); // no-warning
157 void escaped_one_path_1(int cond, void (^callback)(void) CALLED_ONCE) {
159 escape(callback); // no-warning
165 void escaped_one_path_2(int cond, void (^callback)(void) CALLED_ONCE) {
167 escape(callback); // no-warning
173 void escaped_one_path_3(int cond, void (^callback)(void) CALLED_ONCE) {
175 // expected-warning@-1{{'callback' parameter marked 'called_once' is never used when taking false branch}}
180 void escape_in_between_1(void (^callback)(void) CALLED_ONCE) {
181 callback(); // expected-note{{previous call is here}}
183 callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}
186 void escape_in_between_2(int cond, void (^callback)(void) CALLED_ONCE) {
187 callback(); // expected-note{{previous call is here}}
191 callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}
194 void escape_in_between_3(int cond, void (^callback)(void) CALLED_ONCE) {
195 callback(); // expected-note{{previous call is here}}
200 escape_void((__bridge void *)callback);
203 callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}
206 void escaped_as_void_ptr(void (^callback)(void) CALLED_ONCE) {
207 escape_void((__bridge void *)callback); // no-warning
210 void indirect_call_no_warning_1(void (^callback)(void) CALLED_ONCE) {
211 indirect_call(callback); // no-warning
214 void indirect_call_no_warning_2(int cond, void (^callback)(void) CALLED_ONCE) {
216 indirect_call(callback);
223 void 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}}
228 void 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.
238 void block_call_1(void (^callback)(void) CALLED_ONCE) {
239 indirect_call( // expected-note{{previous call is here}}
243 callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}
246 void block_call_2(void (^callback)(void) CALLED_ONCE) {
254 void block_call_3(int cond, void (^callback)(void) CALLED_ONCE) {
257 callback(); // expected-note{{previous call is here}}
259 callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}
263 void block_call_4(int cond, void (^callback)(void) CALLED_ONCE) {
266 // expected-warning@-1{{'callback' parameter marked 'called_once' is never used when taking false branch}}
272 void 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}}
278 void 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}}
283 outer(); // expected-note{{previous call is here}}
284 outer(); // expected-warning{{'outer' parameter marked 'called_once' is called twice}}
287 void 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}}
294 void block_escape_call_1(int cond, void (^callback)(void) CALLED_ONCE) {
295 escape_void((__bridge void *)^{
303 void block_escape_call_2(int cond, void (^callback)(void) CALLED_ONCE) {
304 escape_void((__bridge void *)^{
306 callback(); // expected-note{{previous call is here}}
308 // Double call can still be reported.
309 callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}
313 void 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}}
320 void 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}}
327 void 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
337 void 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}}
344 void 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}}
350 void 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}}
359 void 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}}
365 void 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}}
373 void 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}}
381 void 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}}
388 void 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}}
395 void never_called_switch_case(int cond, void (^callback)(void) CALLED_ONCE) {
403 case 3: // expected-warning{{'callback' parameter marked 'called_once' is never called when handling this case}}
411 void never_called_switch_default(int cond, void (^callback)(void) CALLED_ONCE) {
419 default: // expected-warning{{'callback' parameter marked 'called_once' is never called when handling this case}}
424 void never_called_switch_two_cases(int cond, void (^callback)(void) CALLED_ONCE) {
426 case 1: // expected-warning{{'callback' parameter marked 'called_once' is never called when handling this case}}
428 case 2: // expected-warning{{'callback' parameter marked 'called_once' is never called when handling this case}}
436 void 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}}
453 void exhaustive_switch(enum YesNoOrMaybe cond, void (^callback)(void) CALLED_ONCE) {
468 void 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.
480 void noreturn_1(int cond, void (^callback)(void) CALLED_ONCE) {
489 void noreturn_2(int cond, void (^callback)(void) CALLED_ONCE) {
499 void noreturn_3(int cond, void (^callback)(void) CALLED_ONCE) {
508 void noreturn_4(void (^callback)(void) CALLED_ONCE) {
513 void noreturn_5(int cond, void (^callback)(void) CALLED_ONCE) {
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.
527 void never_called_noreturn_1(int cond, void (^callback)(void) CALLED_ONCE) {
528 // expected-warning@-1{{'callback' parameter marked 'called_once' is never called}}
534 void double_call_noreturn(int cond, void (^callback)(void) CALLED_ONCE) {
535 callback(); // expected-note{{previous call is here}}
539 callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}
545 void call_with_check_1(void (^callback)(void) CALLED_ONCE) {
551 void call_with_check_2(void (^callback)(void) CALLED_ONCE) {
559 void call_with_check_3(void (^callback)(void) CALLED_ONCE) {
560 if (callback != NULL)
565 void call_with_check_4(void (^callback)(void) CALLED_ONCE) {
566 if (NULL != callback)
571 void call_with_check_5(void (^callback)(void) CALLED_ONCE) {
572 if (callback == NULL) {
579 void call_with_check_6(void (^callback)(void) CALLED_ONCE) {
580 if (NULL == callback) {
587 int call_with_check_7(int (^callback)(void) CALLED_ONCE) {
588 return callback ? callback() : 0;
592 void call_with_builtin_check_1(int (^callback)(void) CALLED_ONCE) {
593 if (LIKELY(callback))
598 void call_with_builtin_check_2(int (^callback)(void) CALLED_ONCE) {
599 if (!UNLIKELY(callback)) {
606 void call_with_builtin_check_3(int (^callback)(void) CALLED_ONCE) {
607 if (__builtin_expect((long)callback, 0L)) {
614 void call_with_builtin_check_4(int (^callback)(void) CALLED_ONCE) {
615 if (__builtin_expect(0L, (long)callback)) {
622 void call_with_builtin_check_5(int (^callback)(void) CALLED_ONCE) {
623 if (LIKELY_WITH_PROBA(callback, 0.9))
628 void call_with_builtin_check_6(int (^callback)(void) CALLED_ONCE) {
629 if (!UNLIKELY_WITH_PROBA(callback, 0.9)) {
636 void call_with_builtin_check_7(int (^callback)(void) CALLED_ONCE) {
637 if (UNPRED(callback)) {
644 void call_with_builtin_check_8(int (^callback)(void) CALLED_ONCE) {
645 if (LIKELY(callback != nil))
650 void call_with_builtin_check_9(int (^callback)(void) CALLED_ONCE) {
651 if (!UNLIKELY(callback == NULL))
656 void unreachable_true_branch(void (^callback)(void) CALLED_ONCE) {
665 void unreachable_false_branch(void (^callback)(void) CALLED_ONCE) {
672 void never_called_conv_1(void (^completionHandler)(void)) {
673 // expected-warning@-1{{completion handler is never called}}
676 void never_called_conv_2(void (^completion)(void)) {
677 // expected-warning@-1{{completion handler is never called}}
680 void never_called_conv_WithCompletion(void (^callback)(void)) {
681 // expected-warning@-1{{completion handler is never called}}
684 void indirectly_called_conv(void (^completionHandler)(void)) {
685 indirect_conv(completionHandler);
689 void escape_through_assignment_1(void (^callback)(void) CALLED_ONCE) {
696 void escape_through_assignment_2(void (^callback)(void) CALLED_ONCE) {
697 id escapee = callback;
702 void escape_through_assignment_3(void (^callback1)(void) CALLED_ONCE,
703 void (^callback2)(void) CALLED_ONCE) {
704 id escapee1 = callback1, escapee2 = callback2;
710 void not_called_in_throw_branch_1(id exception, void (^callback)(void) CALLED_ONCE) {
718 void 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}}
725 void conventional_error_path_1(int error, void (^completionHandler)(void)) {
727 // expected-warning@-1{{completion handler is never called when taking true branch}}
728 // This behavior might be tweaked in the future
735 void conventional_error_path_2(int error, void (^callback)(void) CALLED_ONCE) {
736 // Conventions do not apply to explicitly marked parameters.
738 // expected-warning@-1{{'callback' parameter marked 'called_once' is never called when taking true branch}}
745 void 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
751 void suppression_2(int cond, void (^callback)(void) CALLED_ONCE) {
753 (void)callback; // no-warning
759 void 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.
763 // expected-warning@-1{{'callback' parameter marked 'called_once' is never used when taking false branch}}
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;
782 @interface TestClass : TestBase
783 @property(strong) NSMutableArray *handlers;
784 @property(strong) id storedHandler;
785 @property int wasCanceled;
786 @property(getter=hasErrors) int error;
789 @implementation TestClass
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}}
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];
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];
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];
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];
824 - (void)double_indirect_call_6:(void (^)(void))completionHandler {
825 [self indirect_call_conv_3WithCompletion: // expected-note{{previous call is here}}
827 [self indirect_call_conv_3WithCompletion: // expected-warning{{completion handler is called twice}}
831 - (void)double_indirect_call_7:(void (^)(void))completionHandler {
832 [self indirect_call_conv_4: // expected-note{{previous call is here}}
834 [self indirect_call_conv_4: // expected-warning{{completion handler is called twice}}
838 - (void)never_called_trivial:(void (^)(void))CALLED_ONCE callback {
839 // expected-warning@-1{{'callback' parameter marked 'called_once' is never called}}
843 - (void)noreturn:(int)cond callback:(void (^)(void))CALLED_ONCE callback {
852 - (void)escaped_one_path:(int)cond callback:(void (^)(void))CALLED_ONCE callback {
854 [self escape:callback]; // no-warning
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}}
865 callback(); // expected-warning{{'callback' parameter marked 'called_once' is called twice}}
868 - (void)block_call_2:(int)cond callback:(void (^)(void))CALLED_ONCE callback {
872 // expected-warning@-1{{'callback' parameter marked 'called_once' is never used when taking false branch}}
873 [self escape:callback];
878 - (void)block_call_3:(int)cond
879 completionHandler:(void (^)(void))callback {
883 // expected-warning@-1{{completion handler is never used when taking false branch}}
884 [self escape:callback];
889 - (void)block_call_4WithCompletion:(void (^)(void))callback {
892 if ([self condition]) {
893 // expected-warning@-1{{completion handler is never used when taking false branch}}
894 [self escape:callback];
899 - (void)never_called_conv:(void (^)(void))completionHandler {
900 // expected-warning@-1{{completion handler is never called}}
904 - (void)indirectly_called_conv:(void (^)(void))completionHandler {
905 indirect_conv(completionHandler);
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}}
916 - (void)escape_through_assignment:(void (^)(void))completionHandler {
917 _storedHandler = completionHandler;
921 - (void)escape_through_copy:(void (^)(void))completionHandler {
922 _storedHandler = [completionHandler copy];
926 - (void)escape_through_copy_and_autorelease:(void (^)(void))completionHandler {
927 _storedHandler = [[completionHandler copy] autorelease];
931 - (void)complex_escape:(void (^)(void))completionHandler {
932 if (completionHandler) {
933 [_handlers addObject:[[completionHandler copy] autorelease]];
938 - (void)test_crash:(void (^)(void))completionHandler cond:(int)cond {
940 // expected-warning@-1{{completion handler is never used when taking false branch}}
941 for (id _ in _handlers) {
944 [_handlers addObject:completionHandler];
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
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
963 [_handlers addObject:completionHandler];
966 - (void)conventional_error_path_3:(void (^)(void))completionHandler {
968 // expected-warning@-1{{completion handler is never called when taking true branch}}
969 // This behavior might be tweaked in the future
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.
984 // expected-warning@-1{{completion handler is never called when taking false branch}}
989 #define NSAssert(condition, desc, ...) NSLog(desc, ##__VA_ARGS__);
991 - (void)empty_base_1:(void (^)(void))completionHandler {
992 NSAssert(0, @"Subclass must implement");
996 - (void)empty_base_2:(void (^)(void))completionHandler {
1000 - (int)empty_base_3:(void (^)(void))completionHandler {
1005 - (int)empty_base_4:(void (^)(void))completionHandler {
1006 NSAssert(0, @"Subclass must implement");
1011 - (int)empty_base_5:(void (^)(void))completionHandler {
1012 NSAssert(0, @"%@ doesn't support", [self class]);
1018 #define NSAssert(condition, desc, ...) \
1019 if (!(condition)) { \
1020 NSLog(desc, ##__VA_ARGS__); \
1023 - (int)empty_base_6:(void (^)(void))completionHandler {
1024 NSAssert(0, @"%@ doesn't support", [self class]);
1030 #define NSAssert(condition, desc, ...) \
1032 NSLog(desc, ##__VA_ARGS__); \
1035 - (int)empty_base_7:(void (^)(void))completionHandler {
1036 NSAssert(0, @"%@ doesn't support", [self class]);
1041 - (void)two_conditions_1:(int)first
1043 completionHandler:(void (^)(void))completionHandler {
1044 if (first && second) {
1045 // expected-warning@-1{{completion handler is never called when taking false branch}}
1046 completionHandler();
1050 - (void)two_conditions_2:(int)first
1052 completionHandler:(void (^)(void))completionHandler {
1053 if (first || second) {
1054 // expected-warning@-1{{completion handler is never called when taking true branch}}
1058 completionHandler();
1061 - (void)testWithCompletionHandler:(void (^)(void))callback {
1062 if ([self condition]) {
1063 // expected-warning@-1{{completion handler is never called when taking false branch}}
1068 - (void)testWithCompletion:(void (^)(void))callback {
1069 if ([self condition]) {
1070 // expected-warning@-1{{completion handler is never called when taking false branch}}
1075 - (void)test:(int)cond fooWithReplyTo:(void (^)(void))handler {
1077 // expected-warning@-1{{completion handler is never called when taking false branch}}
1082 - (void)test:(int)cond with:(void (^)(void))fooWithCompletionBlock {
1084 // expected-warning@-1{{completion handler is never called when taking false branch}}
1085 fooWithCompletionBlock();
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]) {
1093 completionHandler();
1097 - (void)test_swift_async_none:(int)cond
1098 completionHandler:(void (^)(void))handler __attribute__((swift_async(none))) {
1105 - (void)test_swift_async_param:(int)cond
1106 callback:(void (^)(void))callback
1107 __attribute__((swift_async(swift_private, 2))) {
1109 // expected-warning@-1{{completion handler is never called when taking false branch}}
1114 - (void)test_nil_suggestion:(int)cond1
1116 completion:(void (^)(void))handler {
1119 // expected-note@-1{{previous call is here; set to nil to indicate it cannot be called afterwards}}
1123 handler(); // expected-warning{{completion handler is called twice}}
1127 - (void)test_nil_suppression_1:(int)cond1
1129 completion:(void (^)(void))handler {
1141 - (void)test_nil_suppression_2:(int)cond1
1143 completion:(void (^)(void))handler {
1155 - (void)test_nil_suppression_3:(int)cond1
1157 completion:(void (^)(void))handler {
1169 - (void)test_escape_before_branch:(int)cond
1170 withCompletion:(void (^)(void))handler {
1175 void (^copiedHandler)(void) = ^{
1187 - (void)test_escape_after_branch:(int)cond
1188 withCompletion:(void (^)(void))handler {
1197 - (void)test_termination:(int)cond
1198 withCompletion:(void (^)(void))handler {
1199 // The code below was able to cause non-termination but should be
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}}
1207 typedef void (^DeferredBlock)(void);
1208 static inline void DefferedCallback(DeferredBlock *inBlock) { (*inBlock)(); }
1209 #define _DEFERCONCAT(a, b) a##b
1210 #define _DEFERNAME(a) _DEFERCONCAT(__DeferredVar_, a)
1211 #define DEFER __extension__ __attribute__((cleanup(DefferedCallback), unused)) \
1212 DeferredBlock _DEFERNAME(__COUNTER__) = ^
1214 - (void)test_cleanup_1:(int)cond
1215 withCompletion:(void (^)(void))handler {
1230 - (void)test_cleanup_2:(int)cond
1231 withCompletion:(void (^)(void))handler {
1241 handler(); // expected-note{{previous call is here}}
1244 // We still can warn about double call even in this case.
1245 handler(); // expected-warning{{completion handler is called twice}}
1248 - (void)initWithAdditions:(int)cond
1249 withCompletion:(void (^)(void))handler {