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