null-deref-ps.c revision d7ff4874cbb99b5a8a92121af18792204b210dbb
1// RUN: clang -std=gnu99 -checker-simple -verify %s &&
2// RUN: clang -std=gnu99 -checker-simple -analyzer-store-region -verify %s
3
4#include<stdint.h>
5#include <assert.h>
6
7void f1(int *p) {
8  if (p) *p = 1;
9  else *p = 0; // expected-warning{{ereference}}
10}
11
12struct foo_struct {
13  int x;
14};
15
16int f2(struct foo_struct* p) {
17
18  if (p)
19    p->x = 1;
20
21  return p->x++; // expected-warning{{Dereference of null pointer.}}
22}
23
24int f3(char* x) {
25
26  int i = 2;
27
28  if (x)
29    return x[i - 1];
30
31  return x[i+1]; // expected-warning{{Dereference of null pointer.}}
32}
33
34int f3_b(char* x) {
35
36  int i = 2;
37
38  if (x)
39    return x[i - 1];
40
41  return x[i+1]++; // expected-warning{{Dereference of null pointer.}}
42}
43
44int f4(int *p) {
45
46  uintptr_t x = (uintptr_t) p;
47
48  if (x)
49    return 1;
50
51  int *q = (int*) x;
52  return *q; // expected-warning{{Dereference of null pointer.}}
53}
54
55int f5() {
56
57  char *s = "hello world";
58  return s[0]; // no-warning
59}
60
61int bar(int* p, int q) __attribute__((nonnull));
62
63int f6(int *p) {
64  return !p ? bar(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
65         : bar(p, 0);   // no-warning
66}
67
68int* qux();
69
70int f7(int x) {
71
72  int* p = 0;
73
74  if (0 == x)
75    p = qux();
76
77  if (0 == x)
78    *p = 1; // no-warning
79
80  return x;
81}
82
83int f8(int *p, int *q) {
84  if (!p)
85    if (p)
86      *p = 1; // no-warning
87
88  if (q)
89    if (!q)
90      *q = 1; // no-warning
91}
92
93int* qux();
94
95int f9(unsigned len) {
96  assert (len != 0);
97  int *p = 0;
98  unsigned i;
99
100  for (i = 0; i < len; ++i)
101   p = qux(i);
102
103  return *p++; // no-warning
104}
105
106int f9b(unsigned len) {
107  assert (len > 0);  // note use of '>'
108  int *p = 0;
109  unsigned i;
110
111  for (i = 0; i < len; ++i)
112   p = qux(i);
113
114  return *p++; // no-warning
115}
116
117int* f10(int* p, signed char x, int y) {
118  // This line tests symbolication with compound assignments where the
119  // LHS and RHS have different bitwidths.  The new symbolic value
120  // for 'x' should have a bitwidth of 8.
121  x &= y;
122
123  // This tests that our symbolication worked, and that we correctly test
124  // x against 0 (with the same bitwidth).
125  if (!x) {
126    if (!p) return;
127    *p = 10;
128  }
129  else p = 0;
130
131  if (!x)
132    *p = 5; // no-warning
133
134  return p;
135}
136
137// Test case from <rdar://problem/6407949>
138void f11(unsigned i) {
139  int *x = 0;
140  if (i >= 0) {
141    // always true
142  } else {
143    *x = 42; // no-warning
144  }
145}
146
147void f11b(unsigned i) {
148  int *x = 0;
149  if (i <= ~(unsigned)0) {
150    // always true
151  } else {
152    *x = 42; // no-warning
153  }
154}
155
156