1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference -Wno-tautological-undefined-compare %s
2*67e74705SXin Li
3*67e74705SXin Li void clang_analyzer_eval(bool);
4*67e74705SXin Li
5*67e74705SXin Li typedef typeof(sizeof(int)) size_t;
6*67e74705SXin Li void malloc (size_t);
7*67e74705SXin Li
f1()8*67e74705SXin Li void f1() {
9*67e74705SXin Li int const &i = 3;
10*67e74705SXin Li int b = i;
11*67e74705SXin Li
12*67e74705SXin Li int *p = 0;
13*67e74705SXin Li
14*67e74705SXin Li if (b != 3)
15*67e74705SXin Li *p = 1; // no-warning
16*67e74705SXin Li }
17*67e74705SXin Li
18*67e74705SXin Li char* ptr();
19*67e74705SXin Li char& ref();
20*67e74705SXin Li
21*67e74705SXin Li // These next two tests just shouldn't crash.
t1()22*67e74705SXin Li char t1 () {
23*67e74705SXin Li ref() = 'c';
24*67e74705SXin Li return '0';
25*67e74705SXin Li }
26*67e74705SXin Li
27*67e74705SXin Li // just a sanity test, the same behavior as t1()
t2()28*67e74705SXin Li char t2 () {
29*67e74705SXin Li *ptr() = 'c';
30*67e74705SXin Li return '0';
31*67e74705SXin Li }
32*67e74705SXin Li
33*67e74705SXin Li // Each of the tests below is repeated with pointers as well as references.
34*67e74705SXin Li // This is mostly a sanity check, but then again, both should work!
t3()35*67e74705SXin Li char t3 () {
36*67e74705SXin Li char& r = ref();
37*67e74705SXin Li r = 'c'; // no-warning
38*67e74705SXin Li if (r) return r;
39*67e74705SXin Li return *(char*)0; // no-warning
40*67e74705SXin Li }
41*67e74705SXin Li
t4()42*67e74705SXin Li char t4 () {
43*67e74705SXin Li char* p = ptr();
44*67e74705SXin Li *p = 'c'; // no-warning
45*67e74705SXin Li if (*p) return *p;
46*67e74705SXin Li return *(char*)0; // no-warning
47*67e74705SXin Li }
48*67e74705SXin Li
t5(char & r)49*67e74705SXin Li char t5 (char& r) {
50*67e74705SXin Li r = 'c'; // no-warning
51*67e74705SXin Li if (r) return r;
52*67e74705SXin Li return *(char*)0; // no-warning
53*67e74705SXin Li }
54*67e74705SXin Li
t6(char * p)55*67e74705SXin Li char t6 (char* p) {
56*67e74705SXin Li *p = 'c'; // no-warning
57*67e74705SXin Li if (*p) return *p;
58*67e74705SXin Li return *(char*)0; // no-warning
59*67e74705SXin Li }
60*67e74705SXin Li
61*67e74705SXin Li
62*67e74705SXin Li // PR13440 / <rdar://problem/11977113>
63*67e74705SXin Li // Test that the array-to-pointer decay works for array references as well.
64*67e74705SXin Li // More generally, when we want an lvalue for a reference field, we still need
65*67e74705SXin Li // to do one level of load.
66*67e74705SXin Li namespace PR13440 {
67*67e74705SXin Li typedef int T[1];
68*67e74705SXin Li struct S {
69*67e74705SXin Li T &x;
70*67e74705SXin Li
mPR13440::S71*67e74705SXin Li int *m() { return x; }
72*67e74705SXin Li };
73*67e74705SXin Li
74*67e74705SXin Li struct S2 {
75*67e74705SXin Li int (&x)[1];
76*67e74705SXin Li
mPR13440::S277*67e74705SXin Li int *m() { return x; }
78*67e74705SXin Li
testArrayToPointerDecayWithNonTypedValueRegionPR13440::S279*67e74705SXin Li void testArrayToPointerDecayWithNonTypedValueRegion() {
80*67e74705SXin Li int *p = x;
81*67e74705SXin Li int *q = x;
82*67e74705SXin Li clang_analyzer_eval(p[0] == q[0]); // expected-warning{{TRUE}}
83*67e74705SXin Li }
84*67e74705SXin Li
85*67e74705SXin Li };
86*67e74705SXin Li
test()87*67e74705SXin Li void test() {
88*67e74705SXin Li int a[1];
89*67e74705SXin Li S s = { a };
90*67e74705SXin Li S2 s2 = { a };
91*67e74705SXin Li
92*67e74705SXin Li if (s.x != a) return;
93*67e74705SXin Li if (s2.x != a) return;
94*67e74705SXin Li
95*67e74705SXin Li a[0] = 42;
96*67e74705SXin Li clang_analyzer_eval(s.x[0] == 42); // expected-warning{{TRUE}}
97*67e74705SXin Li clang_analyzer_eval(s2.x[0] == 42); // expected-warning{{TRUE}}
98*67e74705SXin Li }
99*67e74705SXin Li }
100*67e74705SXin Li
testNullReference()101*67e74705SXin Li void testNullReference() {
102*67e74705SXin Li int *x = 0;
103*67e74705SXin Li int &y = *x; // expected-warning{{Dereference of null pointer}}
104*67e74705SXin Li y = 5;
105*67e74705SXin Li }
106*67e74705SXin Li
testRetroactiveNullReference(int * x)107*67e74705SXin Li void testRetroactiveNullReference(int *x) {
108*67e74705SXin Li // According to the C++ standard, there is no such thing as a
109*67e74705SXin Li // "null reference". So the 'if' statement ought to be dead code.
110*67e74705SXin Li // However, Clang (and other compilers) don't actually check that a pointer
111*67e74705SXin Li // value is non-null in the implementation of references, so it is possible
112*67e74705SXin Li // to produce a supposed "null reference" at runtime. The analyzer should
113*67e74705SXin Li // still warn when it can prove such errors.
114*67e74705SXin Li int &y = *x;
115*67e74705SXin Li if (x != 0)
116*67e74705SXin Li return;
117*67e74705SXin Li y = 5; // expected-warning{{Dereference of null pointer}}
118*67e74705SXin Li }
119*67e74705SXin Li
testReferenceAddress(int & x)120*67e74705SXin Li void testReferenceAddress(int &x) {
121*67e74705SXin Li clang_analyzer_eval(&x != 0); // expected-warning{{TRUE}}
122*67e74705SXin Li clang_analyzer_eval(&ref() != 0); // expected-warning{{TRUE}}
123*67e74705SXin Li
124*67e74705SXin Li struct S { int &x; };
125*67e74705SXin Li
126*67e74705SXin Li extern S getS();
127*67e74705SXin Li clang_analyzer_eval(&getS().x != 0); // expected-warning{{TRUE}}
128*67e74705SXin Li
129*67e74705SXin Li extern S *getSP();
130*67e74705SXin Li clang_analyzer_eval(&getSP()->x != 0); // expected-warning{{TRUE}}
131*67e74705SXin Li }
132*67e74705SXin Li
133*67e74705SXin Li
testFunctionPointerReturn(void * opaque)134*67e74705SXin Li void testFunctionPointerReturn(void *opaque) {
135*67e74705SXin Li typedef int &(*RefFn)();
136*67e74705SXin Li
137*67e74705SXin Li RefFn getRef = (RefFn)opaque;
138*67e74705SXin Li
139*67e74705SXin Li // Don't crash writing to or reading from this reference.
140*67e74705SXin Li int &x = getRef();
141*67e74705SXin Li x = 42;
142*67e74705SXin Li clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
143*67e74705SXin Li }
144*67e74705SXin Li
testReturnNullReference()145*67e74705SXin Li int &testReturnNullReference() {
146*67e74705SXin Li int *x = 0;
147*67e74705SXin Li return *x; // expected-warning{{Returning null reference}}
148*67e74705SXin Li }
149*67e74705SXin Li
refFromPointer()150*67e74705SXin Li char &refFromPointer() {
151*67e74705SXin Li return *ptr();
152*67e74705SXin Li }
153*67e74705SXin Li
testReturnReference()154*67e74705SXin Li void testReturnReference() {
155*67e74705SXin Li clang_analyzer_eval(ptr() == 0); // expected-warning{{UNKNOWN}}
156*67e74705SXin Li clang_analyzer_eval(&refFromPointer() == 0); // expected-warning{{FALSE}}
157*67e74705SXin Li }
158*67e74705SXin Li
intRefParam(int & r)159*67e74705SXin Li void intRefParam(int &r) {
160*67e74705SXin Li ;
161*67e74705SXin Li }
162*67e74705SXin Li
test(int * ptr)163*67e74705SXin Li void test(int *ptr) {
164*67e74705SXin Li clang_analyzer_eval(ptr == 0); // expected-warning{{UNKNOWN}}
165*67e74705SXin Li
166*67e74705SXin Li extern void use(int &ref);
167*67e74705SXin Li use(*ptr);
168*67e74705SXin Li
169*67e74705SXin Li clang_analyzer_eval(ptr == 0); // expected-warning{{FALSE}}
170*67e74705SXin Li }
171*67e74705SXin Li
testIntRefParam()172*67e74705SXin Li void testIntRefParam() {
173*67e74705SXin Li int i = 0;
174*67e74705SXin Li intRefParam(i); // no-warning
175*67e74705SXin Li }
176*67e74705SXin Li
refParam(int & byteIndex)177*67e74705SXin Li int refParam(int &byteIndex) {
178*67e74705SXin Li return byteIndex;
179*67e74705SXin Li }
180*67e74705SXin Li
testRefParam(int * p)181*67e74705SXin Li void testRefParam(int *p) {
182*67e74705SXin Li if (p)
183*67e74705SXin Li ;
184*67e74705SXin Li refParam(*p); // expected-warning {{Forming reference to null pointer}}
185*67e74705SXin Li }
186*67e74705SXin Li
ptrRefParam(int * & byteIndex)187*67e74705SXin Li int ptrRefParam(int *&byteIndex) {
188*67e74705SXin Li return *byteIndex; // expected-warning {{Dereference of null pointer}}
189*67e74705SXin Li }
testRefParam2()190*67e74705SXin Li void testRefParam2() {
191*67e74705SXin Li int *p = 0;
192*67e74705SXin Li int *&rp = p;
193*67e74705SXin Li ptrRefParam(rp);
194*67e74705SXin Li }
195*67e74705SXin Li
maybeNull()196*67e74705SXin Li int *maybeNull() {
197*67e74705SXin Li extern bool coin();
198*67e74705SXin Li static int x;
199*67e74705SXin Li return coin() ? &x : 0;
200*67e74705SXin Li }
201*67e74705SXin Li
use(int & x)202*67e74705SXin Li void use(int &x) {
203*67e74705SXin Li x = 1; // no-warning
204*67e74705SXin Li }
205*67e74705SXin Li
testSuppression()206*67e74705SXin Li void testSuppression() {
207*67e74705SXin Li use(*maybeNull());
208*67e74705SXin Li }
209*67e74705SXin Li
210*67e74705SXin Li namespace rdar11212286 {
211*67e74705SXin Li class B{};
212*67e74705SXin Li
test()213*67e74705SXin Li B test() {
214*67e74705SXin Li B *x = 0;
215*67e74705SXin Li return *x; // expected-warning {{Forming reference to null pointer}}
216*67e74705SXin Li }
217*67e74705SXin Li
testif(B * x)218*67e74705SXin Li B testif(B *x) {
219*67e74705SXin Li if (x)
220*67e74705SXin Li ;
221*67e74705SXin Li return *x; // expected-warning {{Forming reference to null pointer}}
222*67e74705SXin Li }
223*67e74705SXin Li
idc(B * x)224*67e74705SXin Li void idc(B *x) {
225*67e74705SXin Li if (x)
226*67e74705SXin Li ;
227*67e74705SXin Li }
228*67e74705SXin Li
testidc(B * x)229*67e74705SXin Li B testidc(B *x) {
230*67e74705SXin Li idc(x);
231*67e74705SXin Li return *x; // no-warning
232*67e74705SXin Li }
233*67e74705SXin Li }
234*67e74705SXin Li
235*67e74705SXin Li namespace PR15694 {
236*67e74705SXin Li class C {
237*67e74705SXin Li bool bit : 1;
bar(const T & obj)238*67e74705SXin Li template <class T> void bar(const T &obj) {}
foo()239*67e74705SXin Li void foo() {
240*67e74705SXin Li bar(bit); // don't crash
241*67e74705SXin Li }
242*67e74705SXin Li };
243*67e74705SXin Li }
244