blob: 32001d8548a22a8b57c28bbe6e13f309f9ba2ea6 [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
26void test_regions(const Shape *A, const Shape *B) {
27 if (dyn_cast<Circle>(A) && !dyn_cast<Circle>(B))
28 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
29}
30
31namespace test_cast {
32void evalLogic(const Shape *S) {
33 const Circle *C = cast<Circle>(S);
34 clang_analyzer_numTimesReached(); // expected-warning {{1}}
35
36 if (S && C)
37 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
38
39 if (S && !C)
40 clang_analyzer_warnIfReached(); // no-warning
41
42 if (!S)
43 clang_analyzer_warnIfReached(); // no-warning
44}
45} // namespace test_cast
46
47namespace test_dyn_cast {
48void evalLogic(const Shape *S) {
49 const Circle *C = dyn_cast<Circle>(S);
50 clang_analyzer_numTimesReached(); // expected-warning {{2}}
51
52 if (S && C)
53 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
54
55 if (S && !C)
56 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
57
58 if (!S)
59 clang_analyzer_warnIfReached(); // no-warning
60}
61} // namespace test_dyn_cast
62
63namespace test_cast_or_null {
64void evalLogic(const Shape *S) {
65 const Circle *C = cast_or_null<Circle>(S);
66 clang_analyzer_numTimesReached(); // expected-warning {{2}}
67
68 if (S && C)
69 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
70
71 if (S && !C)
72 clang_analyzer_warnIfReached(); // no-warning
73
74 if (!S)
75 clang_analyzer_eval(!C); // expected-warning {{TRUE}}
76}
77} // namespace test_cast_or_null
78
79namespace test_dyn_cast_or_null {
80void evalLogic(const Shape *S) {
81 const Circle *C = dyn_cast_or_null<Circle>(S);
82 clang_analyzer_numTimesReached(); // expected-warning {{3}}
83
84 if (S && C)
85 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
86
87 if (S && !C)
88 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
89
90 if (!S)
91 clang_analyzer_eval(!C); // expected-warning {{TRUE}}
92}
93} // namespace test_dyn_cast_or_null
94
95namespace test_cast_as {
96void evalLogic(const Shape *S) {
97 const Circle *C = S->castAs<Circle>();
98 clang_analyzer_numTimesReached(); // expected-warning {{1}}
99
100 if (S && C)
101 clang_analyzer_eval(C == S);
102 // expected-warning@-1 {{TRUE}}
103
104 if (S && !C)
105 clang_analyzer_warnIfReached(); // no-warning
106
107 if (!S)
108 clang_analyzer_warnIfReached(); // no-warning
109}
110} // namespace test_cast_as
111
112namespace test_get_as {
113void evalLogic(const Shape *S) {
114 const Circle *C = S->getAs<Circle>();
115 clang_analyzer_numTimesReached(); // expected-warning {{2}}
116
117 if (S && C)
118 clang_analyzer_eval(C == S);
119 // expected-warning@-1 {{TRUE}}
120
121 if (S && !C)
122 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
123
124 if (!S)
125 clang_analyzer_warnIfReached(); // no-warning
126}
127} // namespace test_get_as
128