1 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,unix.API,osx.API,optin.portability %s -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: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=core,unix.API,osx.API,optin.portability %s -analyzer-output=plist -analyzer-config faux-bodies=true -fblocks -verify -o %t.plist
4 // RUN: %normalize_plist <%t.plist | diff -ub %S/Inputs/expected-plists/unix-fns.c.plist -
5 // RUN: mkdir -p %t.dir
6 // 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
10 struct _opaque_pthread_once_t
{
14 typedef struct _opaque_pthread_once_t __darwin_pthread_once_t
;
15 typedef __darwin_pthread_once_t pthread_once_t
;
16 int pthread_once(pthread_once_t
*, void (*)(void));
17 typedef long unsigned int __darwin_size_t
;
18 typedef __darwin_size_t
size_t;
19 void *calloc(size_t, size_t);
21 void *realloc(void *, size_t);
22 void *reallocf(void *, size_t);
26 struct _os_object_s
*_os_obj
;
27 struct dispatch_object_s
*_do
;
28 struct dispatch_continuation_s
*_dc
;
29 struct dispatch_queue_s
*_dq
;
30 struct dispatch_queue_attr_s
*_dqa
;
31 struct dispatch_group_s
*_dg
;
32 struct dispatch_source_s
*_ds
;
33 struct dispatch_source_attr_s
*_dsa
;
34 struct dispatch_semaphore_s
*_dsema
;
35 struct dispatch_data_s
*_ddata
;
36 struct dispatch_io_s
*_dchannel
;
37 struct dispatch_operation_s
*_doperation
;
38 struct dispatch_disk_s
*_ddisk
;
39 } dispatch_object_t
__attribute__((__transparent_union__
));
40 typedef void (^dispatch_block_t
)(void);
41 typedef struct dispatch_queue_s
*dispatch_queue_t
;
42 void dispatch_sync(dispatch_queue_t queue
, dispatch_block_t block
);
44 typedef long dispatch_once_t
;
47 __attribute__((__nonnull__
))
48 __attribute__((__nothrow__
))
49 void dispatch_once(dispatch_once_t
*predicate
,
50 __attribute__((__noescape__
)) dispatch_block_t block
);
52 // Inlined fast-path dispatch_once defers to the real dispatch_once
56 __attribute__((__always_inline__
))
57 __attribute__((__nonnull__
))
58 __attribute__((__nothrow__
))
59 void _dispatch_once(dispatch_once_t
*predicate
,
60 __attribute__((__noescape__
)) dispatch_block_t block
)
62 if (__builtin_expect((*predicate
), (~0l)) != ~0l) {
63 dispatch_once(predicate
, block
);
65 __asm__
__volatile__("" ::: "memory");
67 __builtin_assume(*predicate
== ~0l);
70 // Macro so that user calls to dispatch_once() call the inlined fast-path
73 #define dispatch_once _dispatch_once
76 #define O_CREAT 0x0200
77 #define O_RDONLY 0x0000
79 int open(const char *, int, ...);
80 int openat(int, const char *, int, ...);
81 int close(int fildes
);
83 void test_open(const char *path
) {
85 fd
= open(path
, O_RDONLY
); // no-warning
89 fd
= open(path
, O_CREAT
); // expected-warning{{Call to 'open' requires a 3rd argument when the 'O_CREAT' flag is set}}
94 void test_open_at(int directory_fd
, const char *relative_path
) {
96 fd
= openat(directory_fd
, relative_path
, O_RDONLY
); // no-warning
100 fd
= openat(directory_fd
, relative_path
, O_CREAT
); // expected-warning{{Call to 'openat' requires a 4th argument when the 'O_CREAT' flag is set}}
105 void test_dispatch_once(void) {
106 dispatch_once_t pred
= 0;
107 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}}
109 void test_dispatch_once_neg(void) {
110 static dispatch_once_t pred
= 0;
111 do { if (__builtin_expect(*(&pred
), ~0l) != ~0l) dispatch_once((&pred
), (^(void) {})); } while (0); // no-warning
114 void test_pthread_once_aux(void);
116 void test_pthread_once(void) {
117 pthread_once_t pred
= {0x30B1BCBA, {0}};
118 pthread_once(&pred
, test_pthread_once_aux
); // expected-warning{{Call to 'pthread_once' uses the local variable 'pred' for the "control" value}}
120 void test_pthread_once_neg(void) {
121 static pthread_once_t pred
= {0x30B1BCBA, {0}};
122 pthread_once(&pred
, test_pthread_once_aux
); // no-warning
125 // PR 2899 - warn of zero-sized allocations to malloc().
127 char* foo
= malloc(0); // expected-warning{{Call to 'malloc' has an allocation size of 0 bytes}}
128 for (unsigned i
= 0; i
< 100; i
++) {
132 void pr2899_nowarn(size_t size
) {
133 char* foo
= malloc(size
); // no-warning
134 for (unsigned i
= 0; i
< 100; i
++) {
138 void test_calloc(void) {
139 char *foo
= calloc(0, 42); // expected-warning{{Call to 'calloc' has an allocation size of 0 bytes}}
140 for (unsigned i
= 0; i
< 100; i
++) {
144 void test_calloc2(void) {
145 char *foo
= calloc(42, 0); // expected-warning{{Call to 'calloc' has an allocation size of 0 bytes}}
146 for (unsigned i
= 0; i
< 100; i
++) {
150 void test_calloc_nowarn(size_t nmemb
, size_t size
) {
151 char *foo
= calloc(nmemb
, size
); // no-warning
152 for (unsigned i
= 0; i
< 100; i
++) {
156 void test_realloc(char *ptr
) {
157 char *foo
= realloc(ptr
, 0); // expected-warning{{Call to 'realloc' has an allocation size of 0 bytes}}
158 for (unsigned i
= 0; i
< 100; i
++) {
162 void test_reallocf(char *ptr
) {
163 char *foo
= reallocf(ptr
, 0); // expected-warning{{Call to 'reallocf' has an allocation size of 0 bytes}}
164 for (unsigned i
= 0; i
< 100; i
++) {
168 void test_realloc_nowarn(char *ptr
, size_t size
) {
169 char *foo
= realloc(ptr
, size
); // no-warning
170 for (unsigned i
= 0; i
< 100; i
++) {
174 void test_reallocf_nowarn(char *ptr
, size_t size
) {
175 char *foo
= reallocf(ptr
, size
); // no-warning
176 for (unsigned i
= 0; i
< 100; i
++) {
180 void test_alloca(void) {
181 char *foo
= alloca(0); // expected-warning{{Call to 'alloca' has an allocation size of 0 bytes}}
182 for(unsigned i
= 0; i
< 100; i
++) {
186 void test_alloca_nowarn(size_t sz
) {
187 char *foo
= alloca(sz
); // no-warning
188 for(unsigned i
= 0; i
< 100; i
++) {
192 void test_builtin_alloca(void) {
193 char *foo2
= __builtin_alloca(0); // expected-warning{{Call to 'alloca' has an allocation size of 0 bytes}}
194 for(unsigned i
= 0; i
< 100; i
++) {
198 void test_builtin_alloca_nowarn(size_t sz
) {
199 char *foo2
= __builtin_alloca(sz
); // no-warning
200 for(unsigned i
= 0; i
< 100; i
++) {
204 void test_valloc(void) {
205 char *foo
= valloc(0); // expected-warning{{Call to 'valloc' has an allocation size of 0 bytes}}
206 for(unsigned i
= 0; i
< 100; i
++) {
210 void test_valloc_nowarn(size_t sz
) {
211 char *foo
= valloc(sz
); // no-warning
212 for(unsigned i
= 0; i
< 100; i
++) {
217 void test_dispatch_once_in_macro(void) {
218 dispatch_once_t pred
= 0;
219 dispatch_once(&pred
, ^(void){}); // expected-warning {{Call to 'dispatch_once' uses the local variable 'pred' for the predicate value}}
222 // Test inlining of dispatch_sync.
223 void test_dispatch_sync(dispatch_queue_t queue
, int *q
) {
225 dispatch_sync(queue
, ^(void){
227 *p
= 1; // expected-warning {{null pointer}}
232 // Test inlining of dispatch_once.
233 void test_inline_dispatch_once(void) {
234 static dispatch_once_t pred
;
236 dispatch_once(&pred
, ^(void) {
237 *p
= 1; // expected-warning {{null}}
241 // Make sure code after call to dispatch once is reached.
242 void test_inline_dispatch_once_reachable(void) {
243 static dispatch_once_t pred
;
245 dispatch_once(&pred
, ^(void) {
249 *p
= 7; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}