summaryrefslogtreecommitdiffstats
path: root/test/Analysis/dtor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/dtor.cpp')
-rw-r--r--test/Analysis/dtor.cpp102
1 files changed, 101 insertions, 1 deletions
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
index f461945..18cd985 100644
--- a/test/Analysis/dtor.cpp
+++ b/test/Analysis/dtor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=inlining -analyzer-config c++-inlining=destructors -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -Wno-null-dereference -verify %s
void clang_analyzer_eval(bool);
void clang_analyzer_checkInlined(bool);
@@ -301,3 +301,103 @@ namespace ExplicitDestructorCall {
obj->VirtualDtor::~VirtualDtor();
}
}
+
+
+namespace MultidimensionalArrays {
+ void testArrayInvalidation() {
+ int i = 42;
+ int j = 42;
+
+ {
+ IntWrapper arr[2][2];
+
+ // There should be no undefined value warnings here.
+ // Eventually these should be TRUE as well, but right now
+ // we can't handle array constructors.
+ clang_analyzer_eval(arr[0][0].x == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(arr[1][1].x == 0); // expected-warning{{UNKNOWN}}
+
+ arr[0][0].x = &i;
+ arr[1][1].x = &j;
+ clang_analyzer_eval(*arr[0][0].x == 42); // expected-warning{{TRUE}}
+ clang_analyzer_eval(*arr[1][1].x == 42); // expected-warning{{TRUE}}
+ }
+
+ // The destructors should have invalidated i and j.
+ clang_analyzer_eval(i == 42); // expected-warning{{UNKNOWN}}
+ 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}}
+ }
+}
OpenPOWER on IntegriCloud