aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/dtor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/dtor.cpp')
-rw-r--r--test/Analysis/dtor.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
index a30823766e..18cd9853f6 100644
--- a/test/Analysis/dtor.cpp
+++ b/test/Analysis/dtor.cpp
@@ -328,3 +328,76 @@ namespace MultidimensionalArrays {
clang_analyzer_eval(j == 42); // expected-warning{{UNKNOWN}}
}
}
+
+namespace LifetimeExtension {
+ struct IntWrapper {
+ int x;
+ IntWrapper(int y) : x(y) {}
+ IntWrapper() {
+ extern void use(int);
+ use(x); // no-warning
+ }
+ };
+
+ struct DerivedWrapper : public IntWrapper {
+ DerivedWrapper(int y) : IntWrapper(y) {}
+ };
+
+ DerivedWrapper get() {
+ return DerivedWrapper(1);
+ }
+
+ void test() {
+ const DerivedWrapper &d = get(); // lifetime extended here
+ }
+
+
+ class SaveOnDestruct {
+ public:
+ static int lastOutput;
+ int value;
+
+ SaveOnDestruct();
+ ~SaveOnDestruct() {
+ lastOutput = value;
+ }
+ };
+
+ void testSimple() {
+ {
+ const SaveOnDestruct &obj = SaveOnDestruct();
+ if (obj.value != 42)
+ return;
+ // destructor called here
+ }
+
+ clang_analyzer_eval(SaveOnDestruct::lastOutput == 42); // expected-warning{{TRUE}}
+ }
+
+ class VirtualDtorBase {
+ public:
+ int value;
+ virtual ~VirtualDtorBase() {}
+ };
+
+ class SaveOnVirtualDestruct : public VirtualDtorBase {
+ public:
+ static int lastOutput;
+
+ SaveOnVirtualDestruct();
+ virtual ~SaveOnVirtualDestruct() {
+ lastOutput = value;
+ }
+ };
+
+ void testVirtual() {
+ {
+ const VirtualDtorBase &obj = SaveOnVirtualDestruct();
+ if (obj.value != 42)
+ return;
+ // destructor called here
+ }
+
+ clang_analyzer_eval(SaveOnVirtualDestruct::lastOutput == 42); // expected-warning{{TRUE}}
+ }
+}