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