1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
2
3void clang_analyzer_eval(int);
4
5#include "Inputs/system-header-simulator.h"
6
7void use(int);
8id foo(int x) {
9  if (x)
10    return 0;
11  static id p = foo(1);
12    clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
13  return p;
14}
15
16const int &globalIntRef = 42;
17
18void testGlobalRef() {
19  // FIXME: Should be TRUE, but should at least not crash.
20  clang_analyzer_eval(globalIntRef == 42); // expected-warning{{UNKNOWN}}
21}
22
23extern int globalInt;
24struct IntWrapper {
25  int value;
26};
27extern struct IntWrapper globalStruct;
28extern void invalidateGlobals();
29
30void testGlobalInvalidation() {
31  clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
32  clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
33
34  if (globalInt != 42)
35    return;
36  if (globalStruct.value != 43)
37    return;
38  clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
39  clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{TRUE}}
40
41  invalidateGlobals();
42  clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
43  clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
44
45  // Repeat to make sure we don't get the /same/ new symbolic values.
46  if (globalInt != 42)
47    return;
48  if (globalStruct.value != 43)
49    return;
50  clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
51  clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{TRUE}}
52
53  invalidateGlobals();
54  clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
55  clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
56}
57
58void testGlobalInvalidationWithDirectBinding() {
59  clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
60  clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
61
62  globalInt = 42;
63  globalStruct.value = 43;
64  clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
65  clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{TRUE}}
66
67  invalidateGlobals();
68  clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
69  clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
70}
71
72void testStaticLocals(void) {
73  static int i;
74  int tmp;
75
76  extern int someSymbolicValue();
77  i = someSymbolicValue();
78
79  if (i == 5) {
80    clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
81    scanf("%d", &tmp);
82    clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
83    invalidateGlobals();
84    clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
85  }
86
87  i = 6;
88  clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
89  scanf("%d", &tmp);
90  clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
91  invalidateGlobals();
92  clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
93
94  i = someSymbolicValue();
95  if (i == 7) {
96    clang_analyzer_eval(i == 7); // expected-warning{{TRUE}}
97    scanf("%d", &i);
98    clang_analyzer_eval(i == 7); // expected-warning{{UNKNOWN}}
99  }
100
101  i = 8;
102  clang_analyzer_eval(i == 8); // expected-warning{{TRUE}}
103  scanf("%d", &i);
104  clang_analyzer_eval(i == 8); // expected-warning{{UNKNOWN}}
105}
106
107void testNonSystemGlobals(void) {
108  extern int i;
109  int tmp;
110
111  if (i == 5) {
112    clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
113    scanf("%d", &tmp);
114    clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
115    invalidateGlobals();
116    clang_analyzer_eval(i == 5); // expected-warning{{UNKNOWN}}
117  }
118
119  i = 6;
120  clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
121  scanf("%d", &tmp);
122  clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
123  invalidateGlobals();
124  clang_analyzer_eval(i == 6); // expected-warning{{UNKNOWN}}
125
126  if (i == 7) {
127    clang_analyzer_eval(i == 7); // expected-warning{{TRUE}}
128    scanf("%d", &i);
129    clang_analyzer_eval(i == 7); // expected-warning{{UNKNOWN}}
130  }
131
132  i = 8;
133  clang_analyzer_eval(i == 8); // expected-warning{{TRUE}}
134  scanf("%d", &i);
135  clang_analyzer_eval(i == 8); // expected-warning{{UNKNOWN}}
136}
137
138void testWrappedGlobals(void) {
139  extern char c;
140  SomeStruct s;
141
142  if (c == 'C') {
143    s.p = &c;
144    clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
145    fakeSystemHeaderCall(0);
146    clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
147    fakeSystemHeaderCall(&s);
148    clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}}
149  }
150
151  c = 'c';
152  s.p = &c;
153  clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}}
154  fakeSystemHeaderCall(0);
155  clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}}
156  fakeSystemHeaderCall(&s);
157  clang_analyzer_eval(c == 'c'); // expected-warning{{UNKNOWN}}
158
159  if (c == 'C') {
160    s.p = &c;
161    clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
162    fakeSystemHeaderCall(0);
163    clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
164    fakeSystemHeaderCall(&s);
165    clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}}
166  }
167}
168
169void testWrappedStaticsViaGlobal(void) {
170  static char c;
171  extern SomeStruct s;
172
173  extern char getSomeChar();
174  c = getSomeChar();
175
176  if (c == 'C') {
177    s.p = &c;
178    clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
179    invalidateGlobals();
180    clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}}
181  }
182
183  c = 'c';
184  s.p = &c;
185  clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}}
186  invalidateGlobals();
187  clang_analyzer_eval(c == 'c'); // expected-warning{{UNKNOWN}}
188}
189