diff options
Diffstat (limited to 'test/Analysis/dtor.cpp')
-rw-r--r-- | test/Analysis/dtor.cpp | 73 |
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}} + } +} |