1 | // RUN: %clang_analyze_cc1 -w -analyzer-checker=core -verify %s |
2 | |
3 | // expected-no-diagnostics |
4 | |
5 | typedef __typeof(sizeof(int)) size_t; |
6 | void *operator new(size_t, void *h) { return h; } |
7 | |
8 | // I've no idea what this code does, but it used to crash, so let's keep it. |
9 | namespace pr37802_v1 { |
10 | struct J { |
11 | int *p; |
12 | }; |
13 | class X { |
14 | void *ar; |
15 | |
16 | public: |
17 | X(void *t) : ar(t) {} |
18 | template <typename T> |
19 | void f(const T &t) { |
20 | new (ar) T(t); |
21 | } |
22 | }; |
23 | class Y { |
24 | public: |
25 | template <typename T> |
26 | void f(T &&); |
27 | void f(J t) { |
28 | f(*t.p); |
29 | } |
30 | }; |
31 | class Z { |
32 | int at() const {} |
33 | |
34 | public: |
35 | Z(const Z &other) { |
36 | other.au(X(this)); |
37 | } |
38 | template <typename T> |
39 | void au(T t) const { |
40 | void *c = const_cast<Z *>(this); |
41 | if (at()) { |
42 | t.f(*static_cast<J *>(c)); |
43 | } else { |
44 | t.f(*static_cast<bool *>(c)); |
45 | } |
46 | } |
47 | }; |
48 | Z g() { |
49 | Z az = g(); |
50 | Z e = az; |
51 | Y d; |
52 | e.au(d); |
53 | } |
54 | } // namespace pr37802_v1 |
55 | |
56 | |
57 | // This slightly modified code crashed differently. |
58 | namespace pr37802_v2 { |
59 | struct J { |
60 | int *p; |
61 | }; |
62 | |
63 | class X { |
64 | void *ar; |
65 | |
66 | public: |
67 | X(void *t) : ar(t) {} |
68 | void f(const J &t) { new (ar) J(t); } |
69 | void f(const bool &t) { new (ar) bool(t); } |
70 | }; |
71 | |
72 | class Y { |
73 | public: |
74 | void boolf(bool &&); |
75 | void f(J &&); |
76 | void f(J t) { boolf(*t.p); } |
77 | }; |
78 | |
79 | class Z { |
80 | int at() const {} |
81 | |
82 | public: |
83 | Z(const Z &other) { other.au(X(this)); } |
84 | void au(X t) const { |
85 | void *c = const_cast<Z *>(this); |
86 | if (at()) { |
87 | t.f(*static_cast<J *>(c)); |
88 | } else { |
89 | t.f(*static_cast<bool *>(c)); |
90 | } |
91 | } |
92 | void au(Y t) const { |
93 | void *c = const_cast<Z *>(this); |
94 | if (at()) { |
95 | t.f(*static_cast<J *>(c)); |
96 | } else { |
97 | } |
98 | } |
99 | }; |
100 | |
101 | Z g() { |
102 | Z az = g(); |
103 | Z e = az; |
104 | Y d; |
105 | e.au(d); |
106 | } |
107 | } // namespace pr37802_v2 |
108 | |