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