1// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
2
3// Perform inline defensive checks.
4void idc(int *p) {
5	if (p)
6		;
7}
8
9int test01(int *p) {
10  if (p)
11    ;
12  return *p; // expected-warning {{Dereference of null pointer}}
13}
14
15int test02(int *p, int *x) {
16  if (p)
17    ;
18  idc(p);
19	if (x)
20		;
21  return *p; // expected-warning {{Dereference of null pointer}}
22}
23
24int test03(int *p, int *x) {
25	idc(p);
26	if (p)
27		;
28	return *p; // False negative
29}
30
31int deref04(int *p) {
32  return *p; // expected-warning {{Dereference of null pointer}}
33}
34
35int test04(int *p) {
36  if (p)
37    ;
38  idc(p);
39  return deref04(p);
40}
41
42int test11(int *q, int *x) {
43	int *p = q;
44	if (q)
45		;
46	if (x)
47		;
48	return *p; // expected-warning{{Dereference of null pointer}}
49}
50
51int test12(int *q) {
52	int *p = q;
53	idc(q);
54	return *p;
55}
56
57int test13(int *q) {
58	int *p = q;
59	idc(p);
60	return *p;
61}
62
63int test21(int *q, int *x) {
64	if (q)
65		;
66	if (x)
67		;
68	int *p = q;
69	return *p; // expected-warning{{Dereference of null pointer}}
70}
71
72int test22(int *q, int *x) {
73  idc(q);
74	if (x)
75		;
76	int *p = q;
77	return *p;
78}
79
80int test23(int *q, int *x) {
81  idc(q);
82	if (x)
83		;
84	int *p = q;
85  if (!p)
86    ;
87	return *p; // False negative
88}
89
90void use(char *p) {
91  if (!p)
92    return;
93  p[0] = 'a';
94}
95
96void test24(char *buffer) {
97  use(buffer);
98  buffer[1] = 'b';
99}
100
101// Ensure idc works on pointers with constant offset.
102void idcchar(const char *s2) {
103  if(s2)
104    ;
105}
106void testConstantOffset(char *value) {
107  char *cursor = value + 5;
108  idcchar(cursor);
109  if (*cursor) {
110    cursor++;
111  }
112}
113
114// Ensure idc works for integer zero values (ex: suppressed div by zero).
115void idcZero(int assume) {
116  if (assume)
117    ;
118}
119
120int idcTriggerZeroValue(int m) {
121  idcZero(m);
122  return 5/m; // no-warning
123}
124
125int idcTriggerZeroValueThroughCall(int i) {
126  return 5/i; // no-warning
127}
128void idcTrackZeroValueThroughCall(int x) {
129  idcZero(x);
130  idcTriggerZeroValueThroughCall(x);
131}
132
133int idcTriggerZeroThroughDoubleAssignemnt(int i) {
134  return 5/i; // no-warning
135}
136void idcTrackZeroThroughDoubleAssignemnt(int x) {
137  idcZero(x);
138  int y = x;
139  int z = y;
140  idcTriggerZeroValueThroughCall(z);
141}
142