blob: e001e4a65e822808012ba91eabbf220b6d34c935 [file] [log] [blame]
Csaba Dabis0202c352019-08-22 00:20:36 +00001// RUN: %clang_analyze_cc1 \
2// RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
3// RUN: -verify %s
4
5#include "Inputs/llvm.h"
6
7void clang_analyzer_numTimesReached();
8void clang_analyzer_warnIfReached();
9void clang_analyzer_eval(bool);
10
11namespace clang {
12struct Shape {
13 template <typename T>
14 const T *castAs() const;
15
16 template <typename T>
17 const T *getAs() const;
18};
19class Triangle : public Shape {};
20class Circle : public Shape {};
21} // namespace clang
22
23using namespace llvm;
24using namespace clang;
25
Csaba Dabis4d716002019-08-22 02:57:59 +000026void test_regions_dyn_cast(const Shape *A, const Shape *B) {
Csaba Dabis0202c352019-08-22 00:20:36 +000027 if (dyn_cast<Circle>(A) && !dyn_cast<Circle>(B))
28 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
29}
30
Csaba Dabis4d716002019-08-22 02:57:59 +000031void test_regions_isa(const Shape *A, const Shape *B) {
32 if (isa<Circle>(A) && !isa<Circle>(B))
33 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
34}
35
Csaba Dabis0202c352019-08-22 00:20:36 +000036namespace test_cast {
37void evalLogic(const Shape *S) {
38 const Circle *C = cast<Circle>(S);
39 clang_analyzer_numTimesReached(); // expected-warning {{1}}
40
41 if (S && C)
42 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
43
44 if (S && !C)
45 clang_analyzer_warnIfReached(); // no-warning
46
47 if (!S)
48 clang_analyzer_warnIfReached(); // no-warning
49}
50} // namespace test_cast
51
52namespace test_dyn_cast {
53void evalLogic(const Shape *S) {
54 const Circle *C = dyn_cast<Circle>(S);
55 clang_analyzer_numTimesReached(); // expected-warning {{2}}
56
57 if (S && C)
58 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
59
60 if (S && !C)
61 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
62
63 if (!S)
64 clang_analyzer_warnIfReached(); // no-warning
65}
66} // namespace test_dyn_cast
67
68namespace test_cast_or_null {
69void evalLogic(const Shape *S) {
70 const Circle *C = cast_or_null<Circle>(S);
71 clang_analyzer_numTimesReached(); // expected-warning {{2}}
72
73 if (S && C)
74 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
75
76 if (S && !C)
77 clang_analyzer_warnIfReached(); // no-warning
78
79 if (!S)
80 clang_analyzer_eval(!C); // expected-warning {{TRUE}}
81}
82} // namespace test_cast_or_null
83
84namespace test_dyn_cast_or_null {
85void evalLogic(const Shape *S) {
86 const Circle *C = dyn_cast_or_null<Circle>(S);
87 clang_analyzer_numTimesReached(); // expected-warning {{3}}
88
89 if (S && C)
90 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
91
92 if (S && !C)
93 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
94
95 if (!S)
96 clang_analyzer_eval(!C); // expected-warning {{TRUE}}
97}
98} // namespace test_dyn_cast_or_null
99
100namespace test_cast_as {
101void evalLogic(const Shape *S) {
102 const Circle *C = S->castAs<Circle>();
103 clang_analyzer_numTimesReached(); // expected-warning {{1}}
104
105 if (S && C)
106 clang_analyzer_eval(C == S);
107 // expected-warning@-1 {{TRUE}}
108
109 if (S && !C)
110 clang_analyzer_warnIfReached(); // no-warning
111
112 if (!S)
113 clang_analyzer_warnIfReached(); // no-warning
114}
115} // namespace test_cast_as
116
117namespace test_get_as {
118void evalLogic(const Shape *S) {
119 const Circle *C = S->getAs<Circle>();
120 clang_analyzer_numTimesReached(); // expected-warning {{2}}
121
122 if (S && C)
123 clang_analyzer_eval(C == S);
124 // expected-warning@-1 {{TRUE}}
125
126 if (S && !C)
127 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
128
129 if (!S)
130 clang_analyzer_warnIfReached(); // no-warning
131}
132} // namespace test_get_as
133