llvm-project/clang/test/Analysis/lifetime-extension.cpp
Artem Dergachev 28ee2d1b09 [analyzer] Construct temporary objects of correct types, destroy them properly.
When constructing a temporary object region, which represents the result of
MaterializeTemporaryExpr, track down the sub-expression for which the temporary
is necessary with a trick similar to the approach used in CodeGen, namely
by using Expr::skipRValueSubobjectAdjustments().

Then, create the temporary object region with type of that sub-expression.
That type would propagate further in a path-sensitive manner.

During destruction of lifetime-extened temporaries, consult the type of
the temporary object region, rather than the type of the lifetime-extending
variable, in order to call the correct destructor (fixes pr17001) and,
at least, not to crash by trying to call a destructor of a plain type
(fixes pr19539).

rdar://problem/29131302
rdar://problem/29131576

Differential Revision: https://reviews.llvm.org/D26839

llvm-svn: 288263
2016-11-30 19:02:44 +00:00

47 lines
1.0 KiB
C++

// RUN: %clang_cc1 -Wno-unused -std=c++11 -analyze -analyzer-checker=debug.ExprInspection -verify %s
void clang_analyzer_eval(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); // expected-warning{{TRUE}}
}
} // end namespace pr17001_call_wrong_destructor
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; // no-crash
const int &y = A().j[1]; // no-crash
const int &z = (A().j[1], A().j[0]); // no-crash
// FIXME: All of these should be TRUE, but constructors aren't inlined.
clang_analyzer_eval(x == 1); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(y == 3); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(z == 2); // expected-warning{{UNKNOWN}}
}
} // end namespace pr19539_crash_on_destroying_an_integer