void clang_analyzer_eval(bool);
void clang_analyzer_checkInlined(bool);
namespace pr17001_call_wrong_destructor {
bool x;
struct A {
int *a;
A() {}
~A() {}
};
struct B : public A {
B() {}
~B() { x = true; }
};
void f() {
{
const A &a = B();
}
clang_analyzer_eval(x); }
}
namespace pr19539_crash_on_destroying_an_integer {
struct A {
int i;
int j[2];
A() : i(1) {
j[0] = 2;
j[1] = 3;
}
~A() {}
};
void f() {
const int &x = A().i; const int &y = A().j[1]; const int &z = (A().j[1], A().j[0]);
clang_analyzer_eval(x == 1);
clang_analyzer_eval(y == 3);
clang_analyzer_eval(z == 2);
#ifdef TEMPORARIES
#else
#endif
}
}
namespace maintain_original_object_address_on_lifetime_extension {
class C {
C **after, **before;
public:
bool x;
C(bool x, C **after, C **before) : x(x), after(after), before(before) {
*before = this;
}
C(const C &c) : x(c.x), after(nullptr), before(nullptr) {}
~C() { if (after) *after = this; }
operator bool() const { return x; }
static C make(C **after, C **before) { return C(false, after, before); }
};
void f1() {
C *after, *before;
{
const C &c = C(true, &after, &before);
}
clang_analyzer_eval(after == before);
#ifdef TEMPORARIES
#else
#endif
}
void f2() {
C *after, *before;
{
C c = C(1, &after, &before);
}
clang_analyzer_eval(after == before); }
void f3(bool coin) {
C *after, *before;
{
const C &c = coin ? C(true, &after, &before) : C(false, &after, &before);
}
clang_analyzer_eval(after == before);
#ifdef TEMPORARIES
#else
#endif
}
void f4(bool coin) {
C *after, *before;
{
const C &c = C(coin, &after, &before) ?: C(false, &after, &before);
}
if (coin) {
clang_analyzer_eval(after == before);
#ifdef TEMPORARIES
#else
#endif
} else {
clang_analyzer_eval(after == before);
#ifdef TEMPORARIES
#else
#endif
}
}
void f5() {
C *after, *before;
{
const bool &x = C(true, &after, &before).x; }
clang_analyzer_eval(after == before);
#ifdef TEMPORARIES
#else
#endif
}
struct A { const C &c;
};
void f6() {
C *after, *before;
{
A a{C(true, &after, &before)};
}
clang_analyzer_eval(after == before); }
void f7() {
C *after, *before;
{
A a = {C(true, &after, &before)};
}
clang_analyzer_eval(after == before); }
void f8() {
C *after, *before;
{
A a[2] = {C(false, nullptr, nullptr), C(true, &after, &before)};
}
clang_analyzer_eval(after == before); }
}
namespace maintain_original_object_address_on_move {
class C {
int *x;
public:
C() : x(nullptr) {}
C(int *x) : x(x) {}
C(const C &c) = delete;
C(C &&c) : x(c.x) { c.x = nullptr; }
C &operator=(C &&c) {
x = c.x;
c.x = nullptr;
return *this;
}
~C() {
if (x)
*x = 0;
}
};
void f1() {
int x = 1;
C c = C(&x);
1 / x; }
void f2() {
int x = 1;
C c;
c = C(&x);
1 / x; }
}
namespace maintain_address_of_copies {
class C;
struct AddressVector {
C *buf[10];
int len;
AddressVector() : len(0) {}
void push(C *c) {
buf[len] = c;
++len;
}
};
class C {
AddressVector &v;
public:
C(AddressVector &v) : v(v) { v.push(this); }
~C() { v.push(this); }
#ifdef MOVES
C(C &&c) : v(c.v) { v.push(this); }
#endif
C(const C &c) : v(c.v) {
#ifdef MOVES
clang_analyzer_checkInlined(false); #else
v.push(this);
#endif
}
static C make(AddressVector &v) { return C(v); }
};
void f1() {
AddressVector v;
{
C c = C(v);
}
clang_analyzer_eval(v.len == 2); clang_analyzer_eval(v.buf[0] == v.buf[1]); }
void f2() {
AddressVector v;
{
const C &c = C::make(v);
}
clang_analyzer_eval(v.len == 2);
clang_analyzer_eval(v.buf[0] == v.buf[1]);
#ifdef TEMPORARIES
#else
#endif
}
void f3() {
AddressVector v;
{
C &&c = C::make(v);
}
clang_analyzer_eval(v.len == 2);
clang_analyzer_eval(v.buf[0] == v.buf[1]);
#ifdef TEMPORARIES
#else
#endif
}
C doubleMake(AddressVector &v) {
return C::make(v);
}
void f4() {
AddressVector v;
{
C c = doubleMake(v);
}
clang_analyzer_eval(v.len == 2); clang_analyzer_eval(v.buf[0] == v.buf[1]); }
}