[AMDGPU][AsmParser][NFC] Get rid of custom default operand handlers.
[llvm-project.git] / clang / test / Analysis / cast-value-logic.cpp
blob52a94f24fba670d4c3a25bad3f750e1717bc71b5
1 // RUN: %clang_analyze_cc1 -std=c++14 \
2 // RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
3 // RUN: -verify %s
5 #include "Inputs/llvm.h"
7 void clang_analyzer_numTimesReached();
8 void clang_analyzer_warnIfReached();
9 void clang_analyzer_eval(bool);
11 namespace clang {
12 struct Shape {
13 template <typename T>
14 const T *castAs() const;
16 template <typename T>
17 const T *getAs() const;
19 virtual double area();
21 class Triangle : public Shape {};
22 class Rectangle : public Shape {};
23 class Hexagon : public Shape {};
24 class Circle : public Shape {
25 public:
26 ~Circle();
28 class SuspiciouslySpecificCircle : public Circle {};
29 } // namespace clang
31 using namespace llvm;
32 using namespace clang;
34 void test_regions_dyn_cast(const Shape *A, const Shape *B) {
35 if (dyn_cast<Circle>(A) && !dyn_cast<Circle>(B))
36 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
39 void test_regions_isa(const Shape *A, const Shape *B) {
40 if (isa<Circle>(A) && !isa<Circle>(B))
41 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
44 void test_regions_isa_variadic(const Shape *A, const Shape *B) {
45 if (isa<Triangle, Rectangle, Hexagon>(A) &&
46 !isa<Rectangle, Hexagon, Circle>(B))
47 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
50 void test_regions_isa_and_nonnull(const Shape *A, const Shape *B) {
51 if (isa_and_nonnull<Circle>(A) && !isa_and_nonnull<Circle>(B))
52 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
55 void test_regions_isa_and_nonnull_variadic(const Shape *A, const Shape *B) {
56 if (isa_and_nonnull<Triangle, Rectangle, Hexagon>(A) &&
57 !isa_and_nonnull<Rectangle, Hexagon, Circle>(B))
58 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
61 namespace test_cast {
62 void evalLogic(const Shape *S) {
63 const Circle *C = cast<Circle>(S);
64 clang_analyzer_numTimesReached(); // expected-warning {{1}}
66 if (S && C)
67 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
69 if (S && !C)
70 clang_analyzer_warnIfReached(); // no-warning
72 if (!S)
73 clang_analyzer_warnIfReached(); // no-warning
75 } // namespace test_cast
77 namespace test_dyn_cast {
78 void evalLogic(const Shape *S) {
79 const Circle *C = dyn_cast<Circle>(S);
80 clang_analyzer_numTimesReached(); // expected-warning {{2}}
82 if (S && C)
83 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
85 if (S && !C)
86 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
88 if (!S)
89 clang_analyzer_warnIfReached(); // no-warning
91 } // namespace test_dyn_cast
93 namespace test_cast_or_null {
94 void evalLogic(const Shape *S) {
95 const Circle *C = cast_or_null<Circle>(S);
96 clang_analyzer_numTimesReached(); // expected-warning {{2}}
98 if (S && C)
99 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
101 if (S && !C)
102 clang_analyzer_warnIfReached(); // no-warning
104 if (!S)
105 clang_analyzer_eval(!C); // expected-warning {{TRUE}}
107 } // namespace test_cast_or_null
109 namespace test_dyn_cast_or_null {
110 void evalLogic(const Shape *S) {
111 const Circle *C = dyn_cast_or_null<Circle>(S);
112 clang_analyzer_numTimesReached(); // expected-warning {{3}}
114 if (S && C)
115 clang_analyzer_eval(C == S); // expected-warning {{TRUE}}
117 if (S && !C)
118 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
120 if (!S)
121 clang_analyzer_eval(!C); // expected-warning {{TRUE}}
123 } // namespace test_dyn_cast_or_null
125 namespace test_cast_as {
126 void evalLogic(const Shape *S) {
127 const Circle *C = S->castAs<Circle>();
128 clang_analyzer_numTimesReached(); // expected-warning {{1}}
130 if (S && C)
131 clang_analyzer_eval(C == S);
132 // expected-warning@-1 {{TRUE}}
134 if (S && !C)
135 clang_analyzer_warnIfReached(); // no-warning
137 if (!S)
138 clang_analyzer_warnIfReached(); // no-warning
140 } // namespace test_cast_as
142 namespace test_get_as {
143 void evalLogic(const Shape *S) {
144 const Circle *C = S->getAs<Circle>();
145 clang_analyzer_numTimesReached(); // expected-warning {{2}}
147 if (S && C)
148 clang_analyzer_eval(C == S);
149 // expected-warning@-1 {{TRUE}}
151 if (S && !C)
152 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
154 if (!S)
155 clang_analyzer_warnIfReached(); // no-warning
157 } // namespace test_get_as
159 namespace crashes {
160 void test_non_reference_null_region_crash(Shape s) {
161 cast<Circle>(s); // no-crash
164 void test_non_reference_temporary_crash() {
165 extern std::unique_ptr<Shape> foo();
166 auto P = foo();
167 auto Q = cast<Circle>(std::move(P)); // no-crash
170 double test_virtual_method_after_call(Shape *S) {
171 if (isa<Circle>(S))
172 return S->area();
173 return S->area() / 2;
176 void test_delete_crash() {
177 extern Circle *makeCircle();
178 Shape *S = makeCircle();
179 delete cast<SuspiciouslySpecificCircle>(S);
181 } // namespace crashes