[RISCV] Simplify usage of SplatPat_simm5_plus1. NFC (#125340)
[llvm-project.git] / clang / test / Analysis / Checkers / WebKit / memory-unsafe-cast.cpp
blob62c945c7a2c242b33e935aa8412c549ef5478793
1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.MemoryUnsafeCastChecker -verify %s
3 class Base { };
4 class Derived : public Base { };
6 template<typename Target, typename Source>
7 Target& downcast_ref(Source& source){
8 [[clang::suppress]]
9 return static_cast<Target&>(source);
12 template<typename Target, typename Source>
13 Target* downcast_ptr(Source* source){
14 [[clang::suppress]]
15 return static_cast<Target*>(source);
18 void test_pointers(Base *base) {
19 Derived *derived_static = static_cast<Derived*>(base);
20 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
21 Derived *derived_reinterpret = reinterpret_cast<Derived*>(base);
22 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
23 Derived *derived_c = (Derived*)base;
24 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
25 Derived *derived_d = downcast_ptr<Derived, Base>(base); // no warning
28 void test_non_pointers(Derived derived) {
29 Base base_static = static_cast<Base>(derived); // no warning
32 void test_refs(Base &base) {
33 Derived &derived_static = static_cast<Derived&>(base);
34 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
35 Derived &derived_reinterpret = reinterpret_cast<Derived&>(base);
36 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
37 Derived &derived_c = (Derived&)base;
38 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
39 Derived &derived_d = downcast_ref<Derived, Base>(base); // no warning
42 class BaseVirtual {
43 virtual void virtual_base_function();
46 class DerivedVirtual : public BaseVirtual {
47 void virtual_base_function() override { }
50 void test_dynamic_casts(BaseVirtual *base_ptr, BaseVirtual &base_ref) {
51 DerivedVirtual *derived_dynamic_ptr = dynamic_cast<DerivedVirtual*>(base_ptr);
52 // expected-warning@-1{{Unsafe cast from base type 'BaseVirtual' to derived type 'DerivedVirtual'}}
53 DerivedVirtual &derived_dynamic_ref = dynamic_cast<DerivedVirtual&>(base_ref);
54 // expected-warning@-1{{Unsafe cast from base type 'BaseVirtual' to derived type 'DerivedVirtual'}}
57 struct BaseStruct { };
58 struct DerivedStruct : BaseStruct { };
60 void test_struct_pointers(struct BaseStruct *base_struct) {
61 struct DerivedStruct *derived_static = static_cast<struct DerivedStruct*>(base_struct);
62 // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}
63 struct DerivedStruct *derived_reinterpret = reinterpret_cast<struct DerivedStruct*>(base_struct);
64 // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}
65 struct DerivedStruct *derived_c = (struct DerivedStruct*)base_struct;
66 // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}
69 typedef struct BaseStruct BStruct;
70 typedef struct DerivedStruct DStruct;
72 void test_struct_refs(BStruct &base_struct) {
73 DStruct &derived_static = static_cast<DStruct&>(base_struct);
74 // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}
75 DStruct &derived_reinterpret = reinterpret_cast<DStruct&>(base_struct);
76 // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}
77 DStruct &derived_c = (DStruct&)base_struct;
78 // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}
81 int counter = 0;
82 void test_recursive(BStruct &base_struct) {
83 if (counter == 5)
84 return;
85 counter++;
86 DStruct &derived_static = static_cast<DStruct&>(base_struct);
87 // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}
90 template<typename T>
91 class BaseTemplate { };
93 template<typename T>
94 class DerivedTemplate : public BaseTemplate<T> { };
96 void test_templates(BaseTemplate<int> *base, BaseTemplate<int> &base_ref) {
97 DerivedTemplate<int> *derived_static = static_cast<DerivedTemplate<int>*>(base);
98 // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}
99 DerivedTemplate<int> *derived_reinterpret = reinterpret_cast<DerivedTemplate<int>*>(base);
100 // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}
101 DerivedTemplate<int> *derived_c = (DerivedTemplate<int>*)base;
102 // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}
103 DerivedTemplate<int> &derived_static_ref = static_cast<DerivedTemplate<int>&>(base_ref);
104 // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}
105 DerivedTemplate<int> &derived_reinterpret_ref = reinterpret_cast<DerivedTemplate<int>&>(base_ref);
106 // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}
107 DerivedTemplate<int> &derived_c_ref = (DerivedTemplate<int>&)base_ref;
108 // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}
111 #define CAST_MACRO_STATIC(X,Y) (static_cast<Y>(X))
112 #define CAST_MACRO_REINTERPRET(X,Y) (reinterpret_cast<Y>(X))
113 #define CAST_MACRO_C(X,Y) ((Y)X)
115 void test_macro_static(Base *base, Derived *derived, Base &base_ref) {
116 Derived *derived_static = CAST_MACRO_STATIC(base, Derived*);
117 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
118 Derived &derived_static_ref = CAST_MACRO_STATIC(base_ref, Derived&);
119 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
120 Base *base_static_same = CAST_MACRO_STATIC(base, Base*); // no warning
121 Base *base_static_upcast = CAST_MACRO_STATIC(derived, Base*); // no warning
124 void test_macro_reinterpret(Base *base, Derived *derived, Base &base_ref) {
125 Derived *derived_reinterpret = CAST_MACRO_REINTERPRET(base, Derived*);
126 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
127 Derived &derived_reinterpret_ref = CAST_MACRO_REINTERPRET(base_ref, Derived&);
128 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
129 Base *base_reinterpret_same = CAST_MACRO_REINTERPRET(base, Base*); // no warning
130 Base *base_reinterpret_upcast = CAST_MACRO_REINTERPRET(derived, Base*); // no warning
133 void test_macro_c(Base *base, Derived *derived, Base &base_ref) {
134 Derived *derived_c = CAST_MACRO_C(base, Derived*);
135 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
136 Derived &derived_c_ref = CAST_MACRO_C(base_ref, Derived&);
137 // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}
138 Base *base_c_same = CAST_MACRO_C(base, Base*); // no warning
139 Base *base_c_upcast = CAST_MACRO_C(derived, Base*); // no warning
142 struct BaseStructCpp {
143 int t;
144 void increment() { t++; }
146 struct DerivedStructCpp : BaseStructCpp {
147 void increment_t() {increment();}
150 void test_struct_cpp_pointers(struct BaseStructCpp *base_struct) {
151 struct DerivedStructCpp *derived_static = static_cast<struct DerivedStructCpp*>(base_struct);
152 // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}
153 struct DerivedStructCpp *derived_reinterpret = reinterpret_cast<struct DerivedStructCpp*>(base_struct);
154 // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}
155 struct DerivedStructCpp *derived_c = (struct DerivedStructCpp*)base_struct;
156 // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}
159 typedef struct BaseStructCpp BStructCpp;
160 typedef struct DerivedStructCpp DStructCpp;
162 void test_struct_cpp_refs(BStructCpp &base_struct, DStructCpp &derived_struct) {
163 DStructCpp &derived_static = static_cast<DStructCpp&>(base_struct);
164 // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}
165 DStructCpp &derived_reinterpret = reinterpret_cast<DStructCpp&>(base_struct);
166 // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}
167 DStructCpp &derived_c = (DStructCpp&)base_struct;
168 // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}
169 BStructCpp &base = (BStructCpp&)derived_struct; // no warning
170 BStructCpp &base_static = static_cast<BStructCpp&>(derived_struct); // no warning
171 BStructCpp &base_reinterpret = reinterpret_cast<BStructCpp&>(derived_struct); // no warning
174 struct stack_st { };
176 #define STACK_OF(type) struct stack_st_##type
178 void test_stack(stack_st *base) {
179 STACK_OF(void) *derived = (STACK_OF(void)*)base;
180 // expected-warning@-1{{Unsafe cast from type 'stack_st' to an unrelated type 'stack_st_void'}}
183 class Parent { };
184 class Child1 : public Parent { };
185 class Child2 : public Parent { };
187 void test_common_parent(Child1 *c1, Child2 *c2) {
188 Child2 *c2_cstyle = (Child2 *)c1;
189 // expected-warning@-1{{Unsafe cast from type 'Child1' to an unrelated type 'Child2'}}
190 Child2 *c2_reinterpret = reinterpret_cast<Child2 *>(c1);
191 // expected-warning@-1{{Unsafe cast from type 'Child1' to an unrelated type 'Child2'}}
194 class Type1 { };
195 class Type2 { };
197 void test_unrelated_ref(Type1 &t1, Type2 &t2) {
198 Type2 &t2_cstyle = (Type2 &)t1;
199 // expected-warning@-1{{Unsafe cast from type 'Type1' to an unrelated type 'Type2'}}
200 Type2 &t2_reinterpret = reinterpret_cast<Type2 &>(t1);
201 // expected-warning@-1{{Unsafe cast from type 'Type1' to an unrelated type 'Type2'}}
202 Type2 &t2_same = reinterpret_cast<Type2 &>(t2); // no warning
206 class VirtualClass1 {
207 virtual void virtual_base_function();
210 class VirtualClass2 {
211 void virtual_base_function();
214 void test_unrelated_virtual(VirtualClass1 &v1) {
215 VirtualClass2 &v2 = dynamic_cast<VirtualClass2 &>(v1);
216 // expected-warning@-1{{Unsafe cast from type 'VirtualClass1' to an unrelated type 'VirtualClass2'}}
219 struct StructA { };
220 struct StructB { };
222 typedef struct StructA StA;
223 typedef struct StructB StB;
225 void test_struct_unrelated_refs(StA &a, StB &b) {
226 StB &b_reinterpret = reinterpret_cast<StB&>(a);
227 // expected-warning@-1{{Unsafe cast from type 'StructA' to an unrelated type 'StructB'}}
228 StB &b_c = (StB&)a;
229 // expected-warning@-1{{Unsafe cast from type 'StructA' to an unrelated type 'StructB'}}
230 StA &a_local = (StA&)b;
231 // expected-warning@-1{{Unsafe cast from type 'StructB' to an unrelated type 'StructA'}}
232 StA &a_reinterpret = reinterpret_cast<StA&>(b);
233 // expected-warning@-1{{Unsafe cast from type 'StructB' to an unrelated type 'StructA'}}
234 StA &a_same = (StA&)a; // no warning
237 template<typename T>
238 class DeferrableRefCounted {
239 public:
240 void deref() const {
241 auto this_to_T = static_cast<const T*>(this); // no warning
245 class SomeArrayClass : public DeferrableRefCounted<SomeArrayClass> { };
247 void test_this_to_template(SomeArrayClass *ptr) {
248 ptr->deref();
251 template<typename WeakPtrFactoryType>
252 class CanMakeWeakPtrBase {
253 public:
254 void initializeWeakPtrFactory() const {
255 auto &this_to_T = static_cast<const WeakPtrFactoryType&>(*this);
259 template<typename T>
260 using CanMakeWeakPtr = CanMakeWeakPtrBase<T>;
262 class EventLoop : public CanMakeWeakPtr<EventLoop> { };
264 void test_this_to_template_ref(EventLoop *ptr) {
265 ptr->initializeWeakPtrFactory();