unix-fns.c revision a4c7a4314ffbe402091695874e93d9b0a79c8099
1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=unix.API,osx.API %s -analyzer-store=region -fblocks -verify
2
3struct _opaque_pthread_once_t {
4  long __sig;
5  char __opaque[8];
6};
7typedef struct _opaque_pthread_once_t    __darwin_pthread_once_t;
8typedef __darwin_pthread_once_t pthread_once_t;
9int pthread_once(pthread_once_t *, void (*)(void));
10typedef long unsigned int __darwin_size_t;
11typedef __darwin_size_t size_t;
12void *malloc(size_t);
13
14typedef void (^dispatch_block_t)(void);
15typedef long dispatch_once_t;
16void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
17
18#ifndef O_CREAT
19#define O_CREAT 0x0200
20#define O_RDONLY 0x0000
21#endif
22int open(const char *, int, ...);
23int close(int fildes);
24
25void test_open(const char *path) {
26  int fd;
27  fd = open(path, O_RDONLY); // no-warning
28  if (!fd)
29    close(fd);
30
31  fd = open(path, O_CREAT); // expected-warning{{Call to 'open' requires a third argument when the 'O_CREAT' flag is set}}
32  if (!fd)
33    close(fd);
34}
35
36void test_dispatch_once() {
37  dispatch_once_t pred = 0;
38  do { if (__builtin_expect(*(&pred), ~0l) != ~0l) dispatch_once((&pred), (^() {})); } while (0); // expected-warning{{Call to 'dispatch_once' uses the local variable 'pred' for the predicate value}}
39}
40void test_dispatch_once_neg() {
41  static dispatch_once_t pred = 0;
42  do { if (__builtin_expect(*(&pred), ~0l) != ~0l) dispatch_once((&pred), (^() {})); } while (0); // no-warning
43}
44
45void test_pthread_once_aux();
46
47void test_pthread_once() {
48  pthread_once_t pred = {0x30B1BCBA, {0}};
49  pthread_once(&pred, test_pthread_once_aux); // expected-warning{{Call to 'pthread_once' uses the local variable 'pred' for the "control" value}}
50}
51void test_pthread_once_neg() {
52  static pthread_once_t pred = {0x30B1BCBA, {0}};
53  pthread_once(&pred, test_pthread_once_aux); // no-warning
54}
55
56// PR 2899 - warn of zero-sized allocations to malloc().
57void pr2899() {
58  char* foo = malloc(0); // expected-warning{{Call to 'malloc' has an allocation size of 0 bytes}}
59  for (unsigned i = 0; i < 100; i++) {
60    foo[i] = 0;
61  }
62}
63void pr2899_nowarn(size_t size) {
64  char* foo = malloc(size); // no-warning
65  for (unsigned i = 0; i < 100; i++) {
66    foo[i] = 0;
67  }
68}
69