[clang-cl] Ignore /Wv and /Wv:17 flags
[llvm-project.git] / clang / test / Analysis / stack-capture-leak-arc.mm
blob1ffee934c890bc19a0cebaa0b1f87e476f684484
1 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.core.StackAddressAsyncEscape -fblocks -fobjc-arc -verify %s
3 typedef struct dispatch_queue_s *dispatch_queue_t;
4 typedef void (^dispatch_block_t)(void);
5 void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
6 typedef long dispatch_once_t;
7 void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
8 typedef long dispatch_time_t;
9 void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block);
10 void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block);
12 extern dispatch_queue_t queue;
13 extern dispatch_once_t *predicate;
14 extern dispatch_time_t when;
16 void test_block_expr_async() {
17   int x = 123;
18   int *p = &x;
20   dispatch_async(queue, ^{
21     *p = 321;
22   });
23   // expected-warning@-3 {{Address of stack memory associated with local variable 'x' \
24 is captured by an asynchronously-executed block}}
27 void test_block_expr_once_no_leak() {
28   int x = 123;
29   int *p = &x;
30   // synchronous, no warning
31   dispatch_once(predicate, ^{
32     *p = 321;
33   });
36 void test_block_expr_after() {
37   int x = 123;
38   int *p = &x;
39   dispatch_after(when, queue, ^{
40     *p = 321;
41   });
42   // expected-warning@-3 {{Address of stack memory associated with local variable 'x' \
43 is captured by an asynchronously-executed block}}
46 void test_block_expr_async_no_leak() {
47   int x = 123;
48   int *p = &x;
49   // no leak
50   dispatch_async(queue, ^{
51     int y = x;
52     ++y;
53   });
56 void test_block_var_async() {
57   int x = 123;
58   int *p = &x;
59   void (^b)(void) = ^void(void) {
60     *p = 1; 
61   };
62   dispatch_async(queue, b);
63   // expected-warning@-1 {{Address of stack memory associated with local variable 'x' \
64 is captured by an asynchronously-executed block}}
67 void test_block_with_ref_async() {
68   int x = 123;
69   int &r = x;
70   void (^b)(void) = ^void(void) {
71     r = 1; 
72   };
73   dispatch_async(queue, b);
74   // expected-warning@-1 {{Address of stack memory associated with local variable 'x' \
75 is captured by an asynchronously-executed block}}
78 dispatch_block_t get_leaking_block() {
79   int leaked_x = 791;
80   int *p = &leaked_x;
81   return ^void(void) {
82     *p = 1; 
83   };
84   // expected-warning@-3 {{Address of stack memory associated with local variable 'leaked_x' \
85 is captured by a returned block}}
88 void test_returned_from_func_block_async() {
89   dispatch_async(queue, get_leaking_block());
90   // expected-warning@-1 {{Address of stack memory associated with local variable 'leaked_x' \
91 is captured by an asynchronously-executed block}}
94 // synchronous, no leak
95 void test_block_var_once() {
96   int x = 123;
97   int *p = &x;
98   void (^b)(void) = ^void(void) {
99     *p = 1; 
100   };
101   dispatch_once(predicate, b); // no-warning
104 void test_block_var_after() {
105   int x = 123;
106   int *p = &x;
107   void (^b)(void) = ^void(void) {
108     *p = 1; 
109   };
110   dispatch_after(when, queue, b);
111   // expected-warning@-1 {{Address of stack memory associated with local variable 'x' \
112 is captured by an asynchronously-executed block}}
115 void test_block_var_async_no_leak() {
116   int x = 123;
117   int *p = &x;
118   void (^b)(void) = ^void(void) {
119     int y = x;
120     ++y; 
121   };
122   dispatch_async(queue, b); // no-warning
125 void test_block_inside_block_async_no_leak() {
126   int x = 123;
127   int *p = &x;
128   void (^inner)(void) = ^void(void) {
129     int y = x;
130     ++y; 
131   };
132   void (^outer)(void) = ^void(void) {
133     int z = x;
134     ++z;
135     inner(); 
136   };
137   dispatch_async(queue, outer); // no-warning
140 dispatch_block_t accept_and_pass_back_block(dispatch_block_t block) {
141   block();
142   return block; // no-warning
145 void test_passing_continuation_no_leak() {
146   int x = 123;
147   int *p = &x;
148   void (^cont)(void) = ^void(void) {
149     *p = 128;
150   };
151   accept_and_pass_back_block(cont); // no-warning
154 @interface NSObject
155 @end
156 @protocol OS_dispatch_semaphore
157 @end
158 typedef NSObject<OS_dispatch_semaphore> *dispatch_semaphore_t;
159 dispatch_semaphore_t dispatch_semaphore_create(long value);
160 long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
161 long dispatch_semaphore_signal(dispatch_semaphore_t dsema);
163 void test_no_leaks_on_semaphore_pattern() {
164   int x = 0;
165   int *p = &x;
166   dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
167   dispatch_async(queue, ^{
168     *p = 1;
169     // Some work.
170     dispatch_semaphore_signal(semaphore);
171   }); // no-warning
173   // Do some other work concurrently with the asynchronous work
174   // Wait for the asynchronous work to finish
175   dispatch_semaphore_wait(semaphore, 1000);
178 void test_dispatch_barrier_sync() {
179   int buf[16];
180   for (int n = 0; n < 16; ++n) {
181     int *ptr = &buf[n];
182     // FIXME: Should not warn. The dispatch_barrier_sync() call ensures
183     // that the block does not outlive 'buf'.
184     dispatch_async(queue, ^{ // expected-warning{{Address of stack memory associated with local variable 'buf' is captured by an asynchronously-executed block}}
185       (void)ptr;
186     });
187   }
188   dispatch_barrier_sync(queue, ^{});