1 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,unix.API,osx.API,optin.portability %s -analyzer-store=region -analyzer-output=plist -analyzer-config faux-bodies=true -fblocks -verify -o %t.plist
2 // RUN: %normalize_plist <%t.plist | diff -ub %S/Inputs/expected-plists/unix-fns.c.plist -
3 // RUN: mkdir -p %t.dir
4 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API,osx.API,optin.portability -analyzer-output=html -analyzer-config faux-bodies=true -fblocks -o %t.dir %s
8 struct _opaque_pthread_once_t
{
12 typedef struct _opaque_pthread_once_t __darwin_pthread_once_t
;
13 typedef __darwin_pthread_once_t pthread_once_t
;
14 int pthread_once(pthread_once_t
*, void (*)(void));
15 typedef long unsigned int __darwin_size_t
;
16 typedef __darwin_size_t
size_t;
17 void *calloc(size_t, size_t);
19 void *realloc(void *, size_t);
20 void *reallocf(void *, size_t);
24 struct _os_object_s
*_os_obj
;
25 struct dispatch_object_s
*_do
;
26 struct dispatch_continuation_s
*_dc
;
27 struct dispatch_queue_s
*_dq
;
28 struct dispatch_queue_attr_s
*_dqa
;
29 struct dispatch_group_s
*_dg
;
30 struct dispatch_source_s
*_ds
;
31 struct dispatch_source_attr_s
*_dsa
;
32 struct dispatch_semaphore_s
*_dsema
;
33 struct dispatch_data_s
*_ddata
;
34 struct dispatch_io_s
*_dchannel
;
35 struct dispatch_operation_s
*_doperation
;
36 struct dispatch_disk_s
*_ddisk
;
37 } dispatch_object_t
__attribute__((__transparent_union__
));
38 typedef void (^dispatch_block_t
)(void);
39 typedef struct dispatch_queue_s
*dispatch_queue_t
;
40 void dispatch_sync(dispatch_queue_t queue
, dispatch_block_t block
);
42 typedef long dispatch_once_t
;
45 __attribute__((__nonnull__
))
46 __attribute__((__nothrow__
))
47 void dispatch_once(dispatch_once_t
*predicate
,
48 __attribute__((__noescape__
)) dispatch_block_t block
);
50 // Inlined fast-path dispatch_once defers to the real dispatch_once
54 __attribute__((__always_inline__
))
55 __attribute__((__nonnull__
))
56 __attribute__((__nothrow__
))
57 void _dispatch_once(dispatch_once_t
*predicate
,
58 __attribute__((__noescape__
)) dispatch_block_t block
)
60 if (__builtin_expect((*predicate
), (~0l)) != ~0l) {
61 dispatch_once(predicate
, block
);
63 __asm__
__volatile__("" ::: "memory");
65 __builtin_assume(*predicate
== ~0l);
68 // Macro so that user calls to dispatch_once() call the inlined fast-path
71 #define dispatch_once _dispatch_once
74 #define O_CREAT 0x0200
75 #define O_RDONLY 0x0000
77 int open(const char *, int, ...);
78 int openat(int, const char *, int, ...);
79 int close(int fildes
);
81 void test_open(const char *path
) {
83 fd
= open(path
, O_RDONLY
); // no-warning
87 fd
= open(path
, O_CREAT
); // expected-warning{{Call to 'open' requires a 3rd argument when the 'O_CREAT' flag is set}}
92 void test_open_at(int directory_fd
, const char *relative_path
) {
94 fd
= openat(directory_fd
, relative_path
, O_RDONLY
); // no-warning
98 fd
= openat(directory_fd
, relative_path
, O_CREAT
); // expected-warning{{Call to 'openat' requires a 4th argument when the 'O_CREAT' flag is set}}
103 void test_dispatch_once(void) {
104 dispatch_once_t pred
= 0;
105 do { if (__builtin_expect(*(&pred
), ~0l) != ~0l) dispatch_once((&pred
), (^(void) {})); } while (0); // expected-warning{{Call to 'dispatch_once' uses the local variable 'pred' for the predicate value}}
107 void test_dispatch_once_neg(void) {
108 static dispatch_once_t pred
= 0;
109 do { if (__builtin_expect(*(&pred
), ~0l) != ~0l) dispatch_once((&pred
), (^(void) {})); } while (0); // no-warning
112 void test_pthread_once_aux(void);
114 void test_pthread_once(void) {
115 pthread_once_t pred
= {0x30B1BCBA, {0}};
116 pthread_once(&pred
, test_pthread_once_aux
); // expected-warning{{Call to 'pthread_once' uses the local variable 'pred' for the "control" value}}
118 void test_pthread_once_neg(void) {
119 static pthread_once_t pred
= {0x30B1BCBA, {0}};
120 pthread_once(&pred
, test_pthread_once_aux
); // no-warning
123 // PR 2899 - warn of zero-sized allocations to malloc().
125 char* foo
= malloc(0); // expected-warning{{Call to 'malloc' has an allocation size of 0 bytes}}
126 for (unsigned i
= 0; i
< 100; i
++) {
130 void pr2899_nowarn(size_t size
) {
131 char* foo
= malloc(size
); // no-warning
132 for (unsigned i
= 0; i
< 100; i
++) {
136 void test_calloc(void) {
137 char *foo
= calloc(0, 42); // expected-warning{{Call to 'calloc' has an allocation size of 0 bytes}}
138 for (unsigned i
= 0; i
< 100; i
++) {
142 void test_calloc2(void) {
143 char *foo
= calloc(42, 0); // expected-warning{{Call to 'calloc' has an allocation size of 0 bytes}}
144 for (unsigned i
= 0; i
< 100; i
++) {
148 void test_calloc_nowarn(size_t nmemb
, size_t size
) {
149 char *foo
= calloc(nmemb
, size
); // no-warning
150 for (unsigned i
= 0; i
< 100; i
++) {
154 void test_realloc(char *ptr
) {
155 char *foo
= realloc(ptr
, 0); // expected-warning{{Call to 'realloc' has an allocation size of 0 bytes}}
156 for (unsigned i
= 0; i
< 100; i
++) {
160 void test_reallocf(char *ptr
) {
161 char *foo
= reallocf(ptr
, 0); // expected-warning{{Call to 'reallocf' has an allocation size of 0 bytes}}
162 for (unsigned i
= 0; i
< 100; i
++) {
166 void test_realloc_nowarn(char *ptr
, size_t size
) {
167 char *foo
= realloc(ptr
, size
); // no-warning
168 for (unsigned i
= 0; i
< 100; i
++) {
172 void test_reallocf_nowarn(char *ptr
, size_t size
) {
173 char *foo
= reallocf(ptr
, size
); // no-warning
174 for (unsigned i
= 0; i
< 100; i
++) {
178 void test_alloca(void) {
179 char *foo
= alloca(0); // expected-warning{{Call to 'alloca' has an allocation size of 0 bytes}}
180 for(unsigned i
= 0; i
< 100; i
++) {
184 void test_alloca_nowarn(size_t sz
) {
185 char *foo
= alloca(sz
); // no-warning
186 for(unsigned i
= 0; i
< 100; i
++) {
190 void test_builtin_alloca(void) {
191 char *foo2
= __builtin_alloca(0); // expected-warning{{Call to 'alloca' has an allocation size of 0 bytes}}
192 for(unsigned i
= 0; i
< 100; i
++) {
196 void test_builtin_alloca_nowarn(size_t sz
) {
197 char *foo2
= __builtin_alloca(sz
); // no-warning
198 for(unsigned i
= 0; i
< 100; i
++) {
202 void test_valloc(void) {
203 char *foo
= valloc(0); // expected-warning{{Call to 'valloc' has an allocation size of 0 bytes}}
204 for(unsigned i
= 0; i
< 100; i
++) {
208 void test_valloc_nowarn(size_t sz
) {
209 char *foo
= valloc(sz
); // no-warning
210 for(unsigned i
= 0; i
< 100; i
++) {
215 void test_dispatch_once_in_macro(void) {
216 dispatch_once_t pred
= 0;
217 dispatch_once(&pred
, ^(void){}); // expected-warning {{Call to 'dispatch_once' uses the local variable 'pred' for the predicate value}}
220 // Test inlining of dispatch_sync.
221 void test_dispatch_sync(dispatch_queue_t queue
, int *q
) {
223 dispatch_sync(queue
, ^(void){
225 *p
= 1; // expected-warning {{null pointer}}
230 // Test inlining of dispatch_once.
231 void test_inline_dispatch_once(void) {
232 static dispatch_once_t pred
;
234 dispatch_once(&pred
, ^(void) {
235 *p
= 1; // expected-warning {{null}}
239 // Make sure code after call to dispatch once is reached.
240 void test_inline_dispatch_once_reachable(void) {
241 static dispatch_once_t pred
;
243 dispatch_once(&pred
, ^(void) {
247 *p
= 7; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}