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