xref: /llvm-project/clang/test/Analysis/plist-output.m (revision 12f78e740c5419f7d1fbcf8f2106e7a40cd1d6f7)
1// RUN: %clang_analyze_cc1 -analyzer-config eagerly-assume=false %s -analyzer-checker=osx.cocoa.RetainCount,deadcode.DeadStores,core -analyzer-output=plist -analyzer-config deadcode.DeadStores:ShowFixIts=true -o %t.plist
2// RUN: %normalize_plist <%t.plist | diff -ub %S/Inputs/expected-plists/plist-output.m.plist -
3
4void test_null_init(void) {
5  int *p = 0;
6  *p = 0xDEADBEEF;
7}
8
9void test_null_assign(void) {
10  int *p;
11  p = 0;
12  *p = 0xDEADBEEF;
13}
14
15void test_null_assign_transitive(void) {
16  int *p;
17  p = 0;
18  int *q = p;
19  *q = 0xDEADBEEF;
20}
21
22void test_null_cond(int *p) {
23  if (!p) {
24    *p = 0xDEADBEEF;
25  }
26}
27
28void test_null_cond_transitive(int *q) {
29  if (!q) {
30    int *p = q;
31    *p = 0xDEADBEEF;
32  }
33}
34
35void test_null_field(void) {
36  struct s { int *p; } x;
37  x.p = 0;
38  *(x.p) = 0xDEADBEEF;
39}
40
41void test_assumptions(int a, int b)
42{
43  if (a == 0) {
44    return;
45  }
46  if (b != 0) {
47    return;
48  }
49  int *p = 0;
50  *p = 0xDEADBEEF;
51}
52
53int *bar_cond_assign(void);
54int test_cond_assign(void) {
55  int *p;
56  if (p = bar_cond_assign())
57    return 1;
58  return *p;
59}
60
61// The following previously crashed when generating extensive diagnostics.
62@interface RDar10797980_help
63@property (readonly) int x;
64@end
65
66@interface RDar10797980 {
67  RDar10797980_help *y;
68}
69- (void) test;
70@end
71
72@implementation RDar10797980
73- (void) test {
74  if (y.x == 1) {
75    int *p = 0;
76    *p = 0xDEADBEEF; // expected-warning {{deference}}
77  }
78}
79
80// The original source for the above Radar contains another problem:
81// if the end-of-path node is an implicit statement, it may not have a valid
82// source location.
83- (void)test2 {
84  if (bar_cond_assign()) {
85    id foo = [[RDar10797980 alloc] init]; // leak
86  }
87  (void)y; // first statement after the 'if' is an implicit 'self' DeclRefExpr
88}
89
90@end
91
92// Test that loops are documented in the path.
93void rdar12280665(void) {
94  for (unsigned i = 0; i < 2; ++i) {
95	  if (i == 1) {
96		  int *p = 0;
97		  *p = 0xDEADBEEF; // expected-warning {{dereference}}
98	  }
99  }
100}
101
102// Test for a "loop executed 0 times" diagnostic.
103int *radar12322528_bar(void);
104
105void radar12322528_for(int x) {
106  int *p = 0;
107  for (unsigned i = 0; i < x; ++i) {
108    p = radar12322528_bar();
109  }
110  *p = 0xDEADBEEF;
111}
112
113void radar12322528_while(int x) {
114  int *p = 0;
115  unsigned i = 0;
116  for ( ; i < x ; ) {
117    ++i;
118    p = radar12322528_bar();
119  }
120  *p = 0xDEADBEEF;
121}
122
123void radar12322528_foo_2(void) {
124  int *p = 0;
125  for (unsigned i = 0; i < 2; ++i) {
126    if (i == 1)
127      break;
128  }
129  *p = 0xDEADBEEF;
130}
131
132void test_loop_diagnostics(void) {
133  int *p = 0;
134  for (int i = 0; i < 2; ++i) { p = 0; }
135  *p = 1;
136}
137
138void test_loop_diagnostics_2(void) {
139  int *p = 0;
140  for (int i = 0; i < 2; ) {
141    ++i;
142    p = 0;
143  }
144  *p = 1;
145}
146
147void test_loop_diagnostics_3(void) {
148  int *p = 0;
149  int i = 0;
150  while (i < 2) {
151    ++i;
152    p = 0;
153  }
154  *p = 1;
155}
156
157void test_loop_fast_enumeration(id arr) {
158  int x;
159  for (id obj in arr) {
160    x = 1;
161  }
162  x += 1;
163}
164
165@interface RDar12114812 { char *p; }
166@end
167
168@implementation RDar12114812
169- (void)test {
170  p = 0;
171  *p = 1;
172}
173@end
174
175// Test diagnostics for initialization of structs.
176void RDar13295437_f(void *i) __attribute__((__nonnull__));
177
178struct  RDar13295437_S { int *i; };
179
180void RDar13295437(void) {
181  struct RDar13295437_S s = {0};
182  struct RDar13295437_S *sp = &s;
183  RDar13295437_f(sp->i);
184}
185
186@interface Foo
187- (int *) returnsPointer;
188@end
189
190int testFoo(Foo *x) {
191  if (x)
192    return 1;
193  return *[x returnsPointer];
194}
195
196