1 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -verify %s
2 
3 void clang_analyzer_eval(bool);
4 
5 class A {
6 public:
f()7     virtual void f(){};
8 
9 };
10 class B : public A{
11 public:
12   int m;
13 };
14 class C : public A{};
15 
16 class BB: public B{};
17 
18 // A lot of the tests below have the if statement in them, which forces the
19 // analyzer to explore both path - when the result is 0 and not. This makes
20 // sure that we definitely know that the result is non-0 (as the result of
21 // the cast).
testDynCastFromRadar()22 int testDynCastFromRadar() {
23     B aa;
24     A *a = &aa;
25     const int* res = 0;
26     B *b = dynamic_cast<B*>(a);
27     static const int i = 5;
28     if(b) {
29         res = &i;
30     } else {
31         res = 0;
32     }
33     return *res; // no warning
34 }
35 
testBaseToBase1()36 int testBaseToBase1() {
37   B b;
38   B *pb = &b;
39   B *pbb = dynamic_cast<B*>(pb);
40   const int* res = 0;
41   static const int i = 5;
42   if (pbb) {
43       res = &i;
44   } else {
45       res = 0;
46   }
47   return *res; // no warning
48 }
49 
testMultipleLevelsOfSubclassing1()50 int testMultipleLevelsOfSubclassing1() {
51   BB bb;
52   B *pb = &bb;
53   A *pa = pb;
54   B *b = dynamic_cast<B*>(pa);
55   const int* res = 0;
56   static const int i = 5;
57   if (b) {
58       res = &i;
59   } else {
60       res = 0;
61   }
62   return *res; // no warning
63 }
64 
testMultipleLevelsOfSubclassing2()65 int testMultipleLevelsOfSubclassing2() {
66   BB bb;
67   A *pbb = &bb;
68   B *b = dynamic_cast<B*>(pbb);
69   BB *s = dynamic_cast<BB*>(b);
70   const int* res = 0;
71   static const int i = 5;
72   if (s) {
73       res = &i;
74   } else {
75       res = 0;
76   }
77   return *res; // no warning
78 }
79 
testMultipleLevelsOfSubclassing3()80 int testMultipleLevelsOfSubclassing3() {
81   BB bb;
82   A *pbb = &bb;
83   B *b = dynamic_cast<B*>(pbb);
84   return b->m; // no warning
85 }
86 
testLHS()87 int testLHS() {
88     B aa;
89     A *a = &aa;
90     return (dynamic_cast<B*>(a))->m;
91 }
92 
testLHS2()93 int testLHS2() {
94     B aa;
95     A *a = &aa;
96     return (*dynamic_cast<B*>(a)).m;
97 }
98 
testDynCastUnknown2(class A * a)99 int testDynCastUnknown2(class A *a) {
100   B *b = dynamic_cast<B*>(a);
101   return b->m; // no warning
102 }
103 
testDynCastUnknown(class A * a)104 int testDynCastUnknown(class A *a) {
105   B *b = dynamic_cast<B*>(a);
106   const int* res = 0;
107   static const int i = 5;
108   if (b) {
109     res = &i;
110   } else {
111     res = 0;
112   }
113   return *res; // expected-warning {{Dereference of null pointer}}
114 }
115 
testDynCastFail2()116 int testDynCastFail2() {
117   C c;
118   A *pa = &c;
119   B *b = dynamic_cast<B*>(pa);
120   return b->m; // expected-warning {{dereference of a null pointer}}
121 }
122 
testLHSFail()123 int testLHSFail() {
124     C c;
125     A *a = &c;
126     return (*dynamic_cast<B*>(a)).m; // expected-warning {{Dereference of null pointer}}
127 }
128 
testBaseToDerivedFail()129 int testBaseToDerivedFail() {
130   A a;
131   B *b = dynamic_cast<B*>(&a);
132   return b->m; // expected-warning {{dereference of a null pointer}}
133 }
134 
testConstZeroFail()135 int testConstZeroFail() {
136   B *b = dynamic_cast<B*>((A *)0);
137   return b->m; // expected-warning {{dereference of a null pointer}}
138 }
139 
testConstZeroFail2()140 int testConstZeroFail2() {
141   A *a = 0;
142   B *b = dynamic_cast<B*>(a);
143   return b->m; // expected-warning {{dereference of a null pointer}}
144 }
145 
testUpcast()146 int testUpcast() {
147   B b;
148   A *a = dynamic_cast<A*>(&b);
149   const int* res = 0;
150   static const int i = 5;
151   if (a) {
152       res = &i;
153   } else {
154       res = 0;
155   }
156   return *res; // no warning
157 }
158 
testCastToVoidStar()159 int testCastToVoidStar() {
160   A a;
161   void *b = dynamic_cast<void*>(&a);
162   const int* res = 0;
163   static const int i = 5;
164   if (b) {
165       res = &i;
166   } else {
167       res = 0;
168   }
169   return *res; // no warning
170 }
171 
testReferenceSuccessfulCast()172 int testReferenceSuccessfulCast() {
173   B rb;
174   B &b = dynamic_cast<B&>(rb);
175   int *x = 0;
176   return *x; // expected-warning {{Dereference of null pointer}}
177 }
178 
testReferenceFailedCast()179 int testReferenceFailedCast() {
180   A a;
181   B &b = dynamic_cast<B&>(a);
182   int *x = 0;
183   return *x; // no warning (An exception is thrown by the cast.)
184 }
185 
186 // Here we allow any outcome of the cast and this is good because there is a
187 // situation where this will fail. So if the user has written the code in this
188 // way, we assume they expect the cast to succeed.
189 // Note, this might need special handling if we track types of symbolic casts
190 // and use them for dynamic_cast handling.
testDynCastMostLikelyWillFail(C * c)191 int testDynCastMostLikelyWillFail(C *c) {
192   B *b = 0;
193   b = dynamic_cast<B*>(c);
194   const int* res = 0;
195   static const int i = 5;
196   if (b) {
197       res = &i;
198   } else {
199       res = 0;
200   }
201 
202   // Note: IPA is turned off for this test because the code below shows how the
203   // dynamic_cast could succeed.
204   return *res; // expected-warning{{Dereference of null pointer}}
205 }
206 
207 class M : public B, public C {};
callTestDynCastMostLikelyWillFail()208 void callTestDynCastMostLikelyWillFail() {
209   M m;
210   testDynCastMostLikelyWillFail(&m);
211 }
212 
213 
testDynCastToMiddleClass()214 void testDynCastToMiddleClass () {
215   class BBB : public BB {};
216   BBB obj;
217   A &ref = obj;
218 
219   // These didn't always correctly layer base regions.
220   B *ptr = dynamic_cast<B*>(&ref);
221   clang_analyzer_eval(ptr != 0); // expected-warning{{TRUE}}
222 
223   // This is actually statically resolved to be a DerivedToBase cast.
224   ptr = dynamic_cast<B*>(&obj);
225   clang_analyzer_eval(ptr != 0); // expected-warning{{TRUE}}
226 }
227 
228 
229 // -----------------------------
230 // False positives/negatives.
231 // -----------------------------
232 
233 // Due to symbolic regions not being typed.
testDynCastFalsePositive(BB * c)234 int testDynCastFalsePositive(BB *c) {
235   B *b = 0;
236   b = dynamic_cast<B*>(c);
237   const int* res = 0;
238   static const int i = 5;
239   if (b) {
240       res = &i;
241   } else {
242       res = 0;
243   }
244   return *res; // expected-warning{{Dereference of null pointer}}
245 }
246 
247 // Does not work when we new an object.
testDynCastFail3()248 int testDynCastFail3() {
249   A *a = new A();
250   B *b = dynamic_cast<B*>(a);
251   return b->m;
252 }
253 
254