xref: /aosp_15_r20/external/clang/test/Analysis/reinterpret-cast.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
2*67e74705SXin Li 
3*67e74705SXin Li void clang_analyzer_eval(bool);
4*67e74705SXin Li 
5*67e74705SXin Li typedef struct Opaque *Data;
6*67e74705SXin Li struct IntWrapper {
7*67e74705SXin Li   int x;
8*67e74705SXin Li };
9*67e74705SXin Li 
10*67e74705SXin Li struct Child : public IntWrapper {
setChild11*67e74705SXin Li   void set() { x = 42; }
12*67e74705SXin Li };
13*67e74705SXin Li 
test(Data data)14*67e74705SXin Li void test(Data data) {
15*67e74705SXin Li   Child *wrapper = reinterpret_cast<Child*>(data);
16*67e74705SXin Li   // Don't crash when upcasting here.
17*67e74705SXin Li   // We don't actually know if 'data' is a Child.
18*67e74705SXin Li   wrapper->set();
19*67e74705SXin Li   clang_analyzer_eval(wrapper->x == 42); // expected-warning{{TRUE}}
20*67e74705SXin Li }
21*67e74705SXin Li 
22*67e74705SXin Li namespace PR14872 {
23*67e74705SXin Li   class Base1 {};
24*67e74705SXin Li   class Derived1 : public Base1 {};
25*67e74705SXin Li 
26*67e74705SXin Li   Derived1 *f1();
27*67e74705SXin Li 
28*67e74705SXin Li   class Base2 {};
29*67e74705SXin Li   class Derived2 : public Base2 {};
30*67e74705SXin Li 
31*67e74705SXin Li   void f2(Base2 *foo);
32*67e74705SXin Li 
f3(void ** out)33*67e74705SXin Li   void f3(void** out)
34*67e74705SXin Li   {
35*67e74705SXin Li     Base1 *v;
36*67e74705SXin Li     v = f1();
37*67e74705SXin Li     *out = v;
38*67e74705SXin Li   }
39*67e74705SXin Li 
test()40*67e74705SXin Li   void test()
41*67e74705SXin Li   {
42*67e74705SXin Li     Derived2 *p;
43*67e74705SXin Li     f3(reinterpret_cast<void**>(&p));
44*67e74705SXin Li     // Don't crash when upcasting here.
45*67e74705SXin Li     // In this case, 'p' actually refers to a Derived1.
46*67e74705SXin Li     f2(p);
47*67e74705SXin Li   }
48*67e74705SXin Li }
49*67e74705SXin Li 
50*67e74705SXin Li namespace rdar13249297 {
51*67e74705SXin Li   struct IntWrapperSubclass : public IntWrapper {};
52*67e74705SXin Li 
53*67e74705SXin Li   struct IntWrapperWrapper {
54*67e74705SXin Li     IntWrapper w;
55*67e74705SXin Li   };
56*67e74705SXin Li 
test(IntWrapperWrapper * ww)57*67e74705SXin Li   void test(IntWrapperWrapper *ww) {
58*67e74705SXin Li     reinterpret_cast<IntWrapperSubclass *>(ww)->x = 42;
59*67e74705SXin Li     clang_analyzer_eval(reinterpret_cast<IntWrapperSubclass *>(ww)->x == 42); // expected-warning{{TRUE}}
60*67e74705SXin Li 
61*67e74705SXin Li     clang_analyzer_eval(ww->w.x == 42); // expected-warning{{TRUE}}
62*67e74705SXin Li     ww->w.x = 0;
63*67e74705SXin Li 
64*67e74705SXin Li     clang_analyzer_eval(reinterpret_cast<IntWrapperSubclass *>(ww)->x == 42); // expected-warning{{FALSE}}
65*67e74705SXin Li   }
66*67e74705SXin Li }
67*67e74705SXin Li 
68*67e74705SXin Li namespace PR15345 {
69*67e74705SXin Li   class C {};
70*67e74705SXin Li 
71*67e74705SXin Li   class Base {
72*67e74705SXin Li   public:
73*67e74705SXin Li     void (*f)();
74*67e74705SXin Li     int x;
75*67e74705SXin Li   };
76*67e74705SXin Li 
77*67e74705SXin Li   class Derived : public Base {};
78*67e74705SXin Li 
test()79*67e74705SXin Li   void test() {
80*67e74705SXin Li 	Derived* p;
81*67e74705SXin Li 	*(reinterpret_cast<void**>(&p)) = new C;
82*67e74705SXin Li 	p->f();
83*67e74705SXin Li 
84*67e74705SXin Li     // We should still be able to do some reasoning about bindings.
85*67e74705SXin Li     p->x = 42;
86*67e74705SXin Li     clang_analyzer_eval(p->x == 42); // expected-warning{{TRUE}}
87*67e74705SXin Li   };
88*67e74705SXin Li }
89*67e74705SXin Li 
trackpointer_std_addressof()90*67e74705SXin Li int trackpointer_std_addressof() {
91*67e74705SXin Li   int x;
92*67e74705SXin Li   int *p = (int*)&reinterpret_cast<const volatile char&>(x);
93*67e74705SXin Li   *p = 6;
94*67e74705SXin Li   return x; // no warning
95*67e74705SXin Li }
96*67e74705SXin Li 
97*67e74705SXin Li void set_x1(int *&);
98*67e74705SXin Li void set_x2(void *&);
radar_13146953(void)99*67e74705SXin Li int radar_13146953(void) {
100*67e74705SXin Li   int *x = 0, *y = 0;
101*67e74705SXin Li 
102*67e74705SXin Li   set_x1(x);
103*67e74705SXin Li   set_x2((void *&)y);
104*67e74705SXin Li   return *x + *y; // no warning
105*67e74705SXin Li }
106*67e74705SXin Li 
107*67e74705SXin Li namespace PR25426 {
108*67e74705SXin Li   struct Base {
109*67e74705SXin Li     int field;
110*67e74705SXin Li   };
111*67e74705SXin Li 
112*67e74705SXin Li   struct Derived : Base { };
113*67e74705SXin Li 
foo(int & p)114*67e74705SXin Li   void foo(int &p) {
115*67e74705SXin Li     Derived &d = (Derived &)(p);
116*67e74705SXin Li     d.field = 2;
117*67e74705SXin Li   }
118*67e74705SXin Li }
119