null-deref-ps.c revision ff944a8c481d6c0f1ad2633e4be9bf8b1dd2a09f
1// RUN: clang -std=gnu99 -checker-simple -verify %s &&
2// RUN: clang -std=gnu99 -checker-simple -analyzer-store-region -analyzer-purge-dead=false -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 bar2(int* p, int q) __attribute__((nonnull(1)));
69
70int f6b(int *p) {
71  return !p ? bar2(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
72         : bar2(p, 0);   // no-warning
73}
74
75int bar3(int*p, int q, int *r) __attribute__((nonnull(1,3)));
76
77int f6c(int *p, int *q) {
78   return !p ? bar3(q, 2, p) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
79             : bar3(p, 2, q); // no-warning
80}
81
82int* qux();
83
84int f7(int x) {
85
86  int* p = 0;
87
88  if (0 == x)
89    p = qux();
90
91  if (0 == x)
92    *p = 1; // no-warning
93
94  return x;
95}
96
97int f8(int *p, int *q) {
98  if (!p)
99    if (p)
100      *p = 1; // no-warning
101
102  if (q)
103    if (!q)
104      *q = 1; // no-warning
105}
106
107int* qux();
108
109int f9(unsigned len) {
110  assert (len != 0);
111  int *p = 0;
112  unsigned i;
113
114  for (i = 0; i < len; ++i)
115   p = qux(i);
116
117  return *p++; // no-warning
118}
119
120int f9b(unsigned len) {
121  assert (len > 0);  // note use of '>'
122  int *p = 0;
123  unsigned i;
124
125  for (i = 0; i < len; ++i)
126   p = qux(i);
127
128  return *p++; // no-warning
129}
130
131int* f10(int* p, signed char x, int y) {
132  // This line tests symbolication with compound assignments where the
133  // LHS and RHS have different bitwidths.  The new symbolic value
134  // for 'x' should have a bitwidth of 8.
135  x &= y;
136
137  // This tests that our symbolication worked, and that we correctly test
138  // x against 0 (with the same bitwidth).
139  if (!x) {
140    if (!p) return;
141    *p = 10;
142  }
143  else p = 0;
144
145  if (!x)
146    *p = 5; // no-warning
147
148  return p;
149}
150
151// Test case from <rdar://problem/6407949>
152void f11(unsigned i) {
153  int *x = 0;
154  if (i >= 0) {
155    // always true
156  } else {
157    *x = 42; // no-warning
158  }
159}
160
161void f11b(unsigned i) {
162  int *x = 0;
163  if (i <= ~(unsigned)0) {
164    // always true
165  } else {
166    *x = 42; // no-warning
167  }
168}
169
170