blob: 531772825f97074ca6bbb845a63aad32dac20fe9 [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;
Artem Dergachev62a76d02019-08-23 03:24:01 +000018
19 virtual double area();
Csaba Dabis0202c352019-08-22 00:20:36 +000020};
21class Triangle : public Shape {};
22class Circle : public Shape {};
23} // namespace clang
24
25using namespace llvm;
26using namespace clang;
27
Csaba Dabis4d716002019-08-22 02:57:59 +000028void test_regions_dyn_cast(const Shape *A, const Shape *B) {
Csaba Dabis0202c352019-08-22 00:20:36 +000029 if (dyn_cast<Circle>(A) && !dyn_cast<Circle>(B))
30 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
31}
32
Csaba Dabis4d716002019-08-22 02:57:59 +000033void test_regions_isa(const Shape *A, const Shape *B) {
34 if (isa<Circle>(A) && !isa<Circle>(B))
35 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
36}
37
Csaba Dabis0202c352019-08-22 00:20:36 +000038namespace test_cast {
39void evalLogic(const Shape *S) {
40 const Circle *C = cast<Circle>(S);
41 clang_analyzer_numTimesReached(); // expected-warning {{1}}
42
43 if (S && C)
44 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
45
46 if (S && !C)
47 clang_analyzer_warnIfReached(); // no-warning
48
49 if (!S)
50 clang_analyzer_warnIfReached(); // no-warning
51}
52} // namespace test_cast
53
54namespace test_dyn_cast {
55void evalLogic(const Shape *S) {
56 const Circle *C = dyn_cast<Circle>(S);
57 clang_analyzer_numTimesReached(); // expected-warning {{2}}
58
59 if (S && C)
60 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
61
62 if (S && !C)
63 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
64
65 if (!S)
66 clang_analyzer_warnIfReached(); // no-warning
67}
68} // namespace test_dyn_cast
69
70namespace test_cast_or_null {
71void evalLogic(const Shape *S) {
72 const Circle *C = cast_or_null<Circle>(S);
73 clang_analyzer_numTimesReached(); // expected-warning {{2}}
74
75 if (S && C)
76 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
77
78 if (S && !C)
79 clang_analyzer_warnIfReached(); // no-warning
80
81 if (!S)
82 clang_analyzer_eval(!C); // expected-warning {{TRUE}}
83}
84} // namespace test_cast_or_null
85
86namespace test_dyn_cast_or_null {
87void evalLogic(const Shape *S) {
88 const Circle *C = dyn_cast_or_null<Circle>(S);
89 clang_analyzer_numTimesReached(); // expected-warning {{3}}
90
91 if (S && C)
92 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
93
94 if (S && !C)
95 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
96
97 if (!S)
98 clang_analyzer_eval(!C); // expected-warning {{TRUE}}
99}
100} // namespace test_dyn_cast_or_null
101
102namespace test_cast_as {
103void evalLogic(const Shape *S) {
104 const Circle *C = S->castAs<Circle>();
105 clang_analyzer_numTimesReached(); // expected-warning {{1}}
106
107 if (S && C)
108 clang_analyzer_eval(C == S);
109 // expected-warning@-1 {{TRUE}}
110
111 if (S && !C)
112 clang_analyzer_warnIfReached(); // no-warning
113
114 if (!S)
115 clang_analyzer_warnIfReached(); // no-warning
116}
117} // namespace test_cast_as
118
119namespace test_get_as {
120void evalLogic(const Shape *S) {
121 const Circle *C = S->getAs<Circle>();
122 clang_analyzer_numTimesReached(); // expected-warning {{2}}
123
124 if (S && C)
125 clang_analyzer_eval(C == S);
126 // expected-warning@-1 {{TRUE}}
127
128 if (S && !C)
129 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
130
131 if (!S)
132 clang_analyzer_warnIfReached(); // no-warning
133}
134} // namespace test_get_as
135
Artem Dergachev0900b772019-08-23 03:23:55 +0000136namespace crashes {
137void test_non_reference_null_region_crash(Shape s) {
138 cast<Circle>(s); // no-crash
139}
Artem Dergachevaf992e62019-08-23 03:23:58 +0000140
141void test_non_reference_temporary_crash() {
142 extern std::unique_ptr<Shape> foo();
143 auto P = foo();
144 auto Q = cast<Circle>(std::move(P)); // no-crash
145}
Artem Dergachev62a76d02019-08-23 03:24:01 +0000146
147double test_virtual_method_after_call(Shape *S) {
148 if (isa<Circle>(S))
149 return S->area();
150 return S->area() / 2;
151}
Artem Dergachev0900b772019-08-23 03:23:55 +0000152} // namespace crashes