unix-fns.c revision c1275da4eb5778eb3c9600e79918ad1fbec589c6
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 *calloc(size_t, size_t);
13void *malloc(size_t);
14void *realloc(void *, size_t);
15
16typedef void (^dispatch_block_t)(void);
17typedef long dispatch_once_t;
18void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
19
20#ifndef O_CREAT
21#define O_CREAT 0x0200
22#define O_RDONLY 0x0000
23#endif
24int open(const char *, int, ...);
25int close(int fildes);
26
27void test_open(const char *path) {
28  int fd;
29  fd = open(path, O_RDONLY); // no-warning
30  if (!fd)
31    close(fd);
32
33  fd = open(path, O_CREAT); // expected-warning{{Call to 'open' requires a third argument when the 'O_CREAT' flag is set}}
34  if (!fd)
35    close(fd);
36}
37
38void test_dispatch_once() {
39  dispatch_once_t pred = 0;
40  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}}
41}
42void test_dispatch_once_neg() {
43  static dispatch_once_t pred = 0;
44  do { if (__builtin_expect(*(&pred), ~0l) != ~0l) dispatch_once((&pred), (^() {})); } while (0); // no-warning
45}
46
47void test_pthread_once_aux();
48
49void test_pthread_once() {
50  pthread_once_t pred = {0x30B1BCBA, {0}};
51  pthread_once(&pred, test_pthread_once_aux); // expected-warning{{Call to 'pthread_once' uses the local variable 'pred' for the "control" value}}
52}
53void test_pthread_once_neg() {
54  static pthread_once_t pred = {0x30B1BCBA, {0}};
55  pthread_once(&pred, test_pthread_once_aux); // no-warning
56}
57
58// PR 2899 - warn of zero-sized allocations to malloc().
59void pr2899() {
60  char* foo = malloc(0); // expected-warning{{Call to 'malloc' has an allocation size of 0 bytes}}
61  for (unsigned i = 0; i < 100; i++) {
62    foo[i] = 0;
63  }
64}
65void pr2899_nowarn(size_t size) {
66  char* foo = malloc(size); // no-warning
67  for (unsigned i = 0; i < 100; i++) {
68    foo[i] = 0;
69  }
70}
71void test_calloc(void) {
72  char *foo = calloc(0, 42); // expected-warning{{Call to 'calloc' has an allocation size of 0 bytes}}
73  for (unsigned i = 0; i < 100; i++) {
74    foo[i] = 0;
75  }
76}
77void test_calloc2(void) {
78  char *foo = calloc(42, 0); // expected-warning{{Call to 'calloc' has an allocation size of 0 bytes}}
79  for (unsigned i = 0; i < 100; i++) {
80    foo[i] = 0;
81  }
82}
83void test_calloc_nowarn(size_t nmemb, size_t size) {
84  char *foo = calloc(nmemb, size); // no-warning
85  for (unsigned i = 0; i < 100; i++) {
86    foo[i] = 0;
87  }
88}
89void test_realloc(char *ptr) {
90  char *foo = realloc(ptr, 0); // expected-warning{{Call to 'realloc' has an allocation size of 0 bytes}}
91  for (unsigned i = 0; i < 100; i++) {
92    foo[i] = 0;
93  }
94}
95void test_realloc_nowarn(char *ptr, size_t size) {
96  char *foo = realloc(ptr, size); // no-warning
97  for (unsigned i = 0; i < 100; i++) {
98    foo[i] = 0;
99  }
100}
101