1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s
3 void clang_analyzer_eval(bool);
5 typedef typeof(sizeof(int)) size_t;
21 // These next two tests just shouldn't crash.
27 // just a sanity test, the same behavior as t1()
33 // Each of the tests below is repeated with pointers as well as references.
34 // This is mostly a sanity check, but then again, both should work!
37 r = 'c'; // no-warning
39 return *(char*)0; // no-warning
44 *p = 'c'; // no-warning
46 return *(char*)0; // no-warning
50 r = 'c'; // no-warning
52 return *(char*)0; // no-warning
56 *p = 'c'; // no-warning
58 return *(char*)0; // no-warning
62 // PR13440 / <rdar://problem/11977113>
63 // Test that the array-to-pointer decay works for array references as well.
64 // More generally, when we want an lvalue for a reference field, we still need
65 // to do one level of load.
71 int *m() { return x; }
77 int *m() { return x; }
86 if (s2.x != a) return;
89 clang_analyzer_eval(s.x[0] == 42); // expected-warning{{TRUE}}
90 clang_analyzer_eval(s2.x[0] == 42); // expected-warning{{TRUE}}
94 void testNullReference() {
96 int &y = *x; // expected-warning{{Dereference of null pointer}}
100 void testRetroactiveNullReference(int *x) {
101 // According to the C++ standard, there is no such thing as a
102 // "null reference". So the 'if' statement ought to be dead code.
103 // However, Clang (and other compilers) don't actually check that a pointer
104 // value is non-null in the implementation of references, so it is possible
105 // to produce a supposed "null reference" at runtime. The analyzer shoeuld
106 // still warn when it can prove such errors.
110 y = 5; // expected-warning{{Dereference of null pointer}}
113 void testReferenceAddress(int &x) {
114 clang_analyzer_eval(&x != 0); // expected-warning{{TRUE}}
115 clang_analyzer_eval(&ref() != 0); // expected-warning{{TRUE}}
117 struct S { int &x; };
120 clang_analyzer_eval(&getS().x != 0); // expected-warning{{TRUE}}
123 clang_analyzer_eval(&getSP()->x != 0); // expected-warning{{TRUE}}
127 void testFunctionPointerReturn(void *opaque) {
128 typedef int &(*RefFn)();
130 RefFn getRef = (RefFn)opaque;
132 // Don't crash writing to or reading from this reference.
135 clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
138 int &testReturnNullReference() {
140 return *x; // expected-warning{{Returning null reference}}
143 char &refFromPointer() {
147 void testReturnReference() {
148 clang_analyzer_eval(ptr() == 0); // expected-warning{{UNKNOWN}}
149 clang_analyzer_eval(&refFromPointer() == 0); // expected-warning{{FALSE}}
152 void intRefParam(int &r) {
156 void test(int *ptr) {
157 clang_analyzer_eval(ptr == 0); // expected-warning{{UNKNOWN}}
159 extern void use(int &ref);
162 clang_analyzer_eval(ptr == 0); // expected-warning{{FALSE}}
165 void testIntRefParam() {
167 intRefParam(i); // no-warning
170 int refParam(int &byteIndex) {
174 void testRefParam(int *p) {
177 refParam(*p); // expected-warning {{Forming reference to null pointer}}
180 int ptrRefParam(int *&byteIndex) {
181 return *byteIndex; // expected-warning {{Dereference of null pointer}}
183 void testRefParam2() {
192 return coin() ? &x : 0;
199 void testSuppression() {
203 namespace rdar11212286 {
208 return *x; // expected-warning {{Forming reference to null pointer}}
214 return *x; // expected-warning {{Forming reference to null pointer}}
224 return *x; // no-warning