1 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -verify %s
3 void clang_analyzer_eval(bool);
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
22 int testDynCastFromRadar() {
26 B
*b
= dynamic_cast<B
*>(a
);
27 static const int i
= 5;
33 return *res
; // no warning
36 int testBaseToBase1() {
39 B
*pbb
= dynamic_cast<B
*>(pb
);
41 static const int i
= 5;
47 return *res
; // no warning
50 int testMultipleLevelsOfSubclassing1() {
54 B
*b
= dynamic_cast<B
*>(pa
);
56 static const int i
= 5;
62 return *res
; // no warning
65 int testMultipleLevelsOfSubclassing2() {
68 B
*b
= dynamic_cast<B
*>(pbb
);
69 BB
*s
= dynamic_cast<BB
*>(b
);
71 static const int i
= 5;
77 return *res
; // no warning
80 int testMultipleLevelsOfSubclassing3() {
83 B
*b
= dynamic_cast<B
*>(pbb
);
84 return b
->m
; // no warning
90 return (dynamic_cast<B
*>(a
))->m
;
96 return (*dynamic_cast<B
*>(a
)).m
;
99 int testDynCastUnknown2(class A
*a
) {
100 B
*b
= dynamic_cast<B
*>(a
);
101 return b
->m
; // no warning
104 int testDynCastUnknown(class A
*a
) {
105 B
*b
= dynamic_cast<B
*>(a
);
107 static const int i
= 5;
113 return *res
; // expected-warning {{Dereference of null pointer}}
116 int testDynCastFail2() {
119 B
*b
= dynamic_cast<B
*>(pa
);
120 return b
->m
; // expected-warning {{dereference of a null pointer}}
126 return (*dynamic_cast<B
*>(a
)).m
; // expected-warning {{Dereference of null pointer}}
129 int testBaseToDerivedFail() {
131 B
*b
= dynamic_cast<B
*>(&a
);
132 return b
->m
; // expected-warning {{dereference of a null pointer}}
135 int testConstZeroFail() {
136 B
*b
= dynamic_cast<B
*>((A
*)0);
137 return b
->m
; // expected-warning {{dereference of a null pointer}}
140 int testConstZeroFail2() {
142 B
*b
= dynamic_cast<B
*>(a
);
143 return b
->m
; // expected-warning {{dereference of a null pointer}}
148 A
*a
= dynamic_cast<A
*>(&b
);
150 static const int i
= 5;
156 return *res
; // no warning
159 int testCastToVoidStar() {
161 void *b
= dynamic_cast<void*>(&a
);
163 static const int i
= 5;
169 return *res
; // no warning
172 int testReferenceSuccessfulCast() {
174 B
&b
= dynamic_cast<B
&>(rb
);
176 return *x
; // expected-warning {{Dereference of null pointer}}
179 int testReferenceFailedCast() {
181 B
&b
= dynamic_cast<B
&>(a
);
183 return *x
; // no warning (An exception is thrown by the cast.)
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.
191 int testDynCastMostLikelyWillFail(C
*c
) {
193 b
= dynamic_cast<B
*>(c
);
195 static const int i
= 5;
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}}
207 class M
: public B
, public C
{};
208 void callTestDynCastMostLikelyWillFail() {
210 testDynCastMostLikelyWillFail(&m
);
214 void testDynCastToMiddleClass () {
215 class BBB
: public BB
{};
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}}
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}}
229 // -----------------------------
230 // False positives/negatives.
231 // -----------------------------
233 // Due to symbolic regions not being typed.
234 int testDynCastFalsePositive(BB
*c
) {
236 b
= dynamic_cast<B
*>(c
);
238 static const int i
= 5;
244 return *res
; // expected-warning{{Dereference of null pointer}}
247 // Does not work when we new an object.
248 int testDynCastFail3() {
250 B
*b
= dynamic_cast<B
*>(a
);