135dbd0b1SArtem Dergachev // RUN: %clang_analyze_cc1 -w -analyzer-checker=core -verify %s 235dbd0b1SArtem Dergachev 335dbd0b1SArtem Dergachev // expected-no-diagnostics 435dbd0b1SArtem Dergachev 5*fec4c1a1SArtem Dergachev typedef __typeof(sizeof(int)) size_t; operator new(size_t,void * h)6*fec4c1a1SArtem Dergachevvoid *operator new(size_t, void *h) { return h; } 735dbd0b1SArtem Dergachev 835dbd0b1SArtem Dergachev // I've no idea what this code does, but it used to crash, so let's keep it. 935dbd0b1SArtem Dergachev namespace pr37802_v1 { 1035dbd0b1SArtem Dergachev struct J { 1135dbd0b1SArtem Dergachev int *p; 1235dbd0b1SArtem Dergachev }; 1335dbd0b1SArtem Dergachev class X { 1435dbd0b1SArtem Dergachev void *ar; 1535dbd0b1SArtem Dergachev 1635dbd0b1SArtem Dergachev public: X(void * t)1735dbd0b1SArtem Dergachev X(void *t) : ar(t) {} 1835dbd0b1SArtem Dergachev template <typename T> f(const T & t)1935dbd0b1SArtem Dergachev void f(const T &t) { 2035dbd0b1SArtem Dergachev new (ar) T(t); 2135dbd0b1SArtem Dergachev } 2235dbd0b1SArtem Dergachev }; 2335dbd0b1SArtem Dergachev class Y { 2435dbd0b1SArtem Dergachev public: 2535dbd0b1SArtem Dergachev template <typename T> 2635dbd0b1SArtem Dergachev void f(T &&); f(J t)2735dbd0b1SArtem Dergachev void f(J t) { 2835dbd0b1SArtem Dergachev f(*t.p); 2935dbd0b1SArtem Dergachev } 3035dbd0b1SArtem Dergachev }; 3135dbd0b1SArtem Dergachev class Z { at() const3235dbd0b1SArtem Dergachev int at() const {} 3335dbd0b1SArtem Dergachev 3435dbd0b1SArtem Dergachev public: Z(const Z & other)3535dbd0b1SArtem Dergachev Z(const Z &other) { 3635dbd0b1SArtem Dergachev other.au(X(this)); 3735dbd0b1SArtem Dergachev } 3835dbd0b1SArtem Dergachev template <typename T> au(T t) const3935dbd0b1SArtem Dergachev void au(T t) const { 4035dbd0b1SArtem Dergachev void *c = const_cast<Z *>(this); 4135dbd0b1SArtem Dergachev if (at()) { 4235dbd0b1SArtem Dergachev t.f(*static_cast<J *>(c)); 4335dbd0b1SArtem Dergachev } else { 4435dbd0b1SArtem Dergachev t.f(*static_cast<bool *>(c)); 4535dbd0b1SArtem Dergachev } 4635dbd0b1SArtem Dergachev } 4735dbd0b1SArtem Dergachev }; g()4835dbd0b1SArtem DergachevZ g() { 4935dbd0b1SArtem Dergachev Z az = g(); 5035dbd0b1SArtem Dergachev Z e = az; 5135dbd0b1SArtem Dergachev Y d; 5235dbd0b1SArtem Dergachev e.au(d); 5335dbd0b1SArtem Dergachev } 5435dbd0b1SArtem Dergachev } // namespace pr37802_v1 5535dbd0b1SArtem Dergachev 5635dbd0b1SArtem Dergachev 5735dbd0b1SArtem Dergachev // This slightly modified code crashed differently. 5835dbd0b1SArtem Dergachev namespace pr37802_v2 { 5935dbd0b1SArtem Dergachev struct J { 6035dbd0b1SArtem Dergachev int *p; 6135dbd0b1SArtem Dergachev }; 6235dbd0b1SArtem Dergachev 6335dbd0b1SArtem Dergachev class X { 6435dbd0b1SArtem Dergachev void *ar; 6535dbd0b1SArtem Dergachev 6635dbd0b1SArtem Dergachev public: X(void * t)6735dbd0b1SArtem Dergachev X(void *t) : ar(t) {} f(const J & t)6835dbd0b1SArtem Dergachev void f(const J &t) { new (ar) J(t); } f(const bool & t)6935dbd0b1SArtem Dergachev void f(const bool &t) { new (ar) bool(t); } 7035dbd0b1SArtem Dergachev }; 7135dbd0b1SArtem Dergachev 7235dbd0b1SArtem Dergachev class Y { 7335dbd0b1SArtem Dergachev public: 7435dbd0b1SArtem Dergachev void boolf(bool &&); 7535dbd0b1SArtem Dergachev void f(J &&); f(J t)7635dbd0b1SArtem Dergachev void f(J t) { boolf(*t.p); } 7735dbd0b1SArtem Dergachev }; 7835dbd0b1SArtem Dergachev 7935dbd0b1SArtem Dergachev class Z { at() const8035dbd0b1SArtem Dergachev int at() const {} 8135dbd0b1SArtem Dergachev 8235dbd0b1SArtem Dergachev public: Z(const Z & other)8335dbd0b1SArtem Dergachev Z(const Z &other) { other.au(X(this)); } au(X t) const8435dbd0b1SArtem Dergachev void au(X t) const { 8535dbd0b1SArtem Dergachev void *c = const_cast<Z *>(this); 8635dbd0b1SArtem Dergachev if (at()) { 8735dbd0b1SArtem Dergachev t.f(*static_cast<J *>(c)); 8835dbd0b1SArtem Dergachev } else { 8935dbd0b1SArtem Dergachev t.f(*static_cast<bool *>(c)); 9035dbd0b1SArtem Dergachev } 9135dbd0b1SArtem Dergachev } au(Y t) const9235dbd0b1SArtem Dergachev void au(Y t) const { 9335dbd0b1SArtem Dergachev void *c = const_cast<Z *>(this); 9435dbd0b1SArtem Dergachev if (at()) { 9535dbd0b1SArtem Dergachev t.f(*static_cast<J *>(c)); 9635dbd0b1SArtem Dergachev } else { 9735dbd0b1SArtem Dergachev } 9835dbd0b1SArtem Dergachev } 9935dbd0b1SArtem Dergachev }; 10035dbd0b1SArtem Dergachev g()10135dbd0b1SArtem DergachevZ g() { 10235dbd0b1SArtem Dergachev Z az = g(); 10335dbd0b1SArtem Dergachev Z e = az; 10435dbd0b1SArtem Dergachev Y d; 10535dbd0b1SArtem Dergachev e.au(d); 10635dbd0b1SArtem Dergachev } 10735dbd0b1SArtem Dergachev } // namespace pr37802_v2 108