about summary refs log tree commit diff homepage
path: root/test/CXX/symex/libc++/landingpad.cpp
diff options
context:
space:
mode:
authorFelix Rath <felix.rath@comsys.rwth-aachen.de>2020-05-22 14:09:10 +0200
committerMartinNowack <2443641+MartinNowack@users.noreply.github.com>2020-10-12 11:19:24 +0100
commitc09306ffd894f95be195723327d5b17dca73ebd1 (patch)
tree592773383280012bce8856b28503ab61de0deb98 /test/CXX/symex/libc++/landingpad.cpp
parentd920e049fa955877f772188fdc58cab1b31aabc9 (diff)
downloadklee-c09306ffd894f95be195723327d5b17dca73ebd1.tar.gz
Implemented support for C++ Exceptions
We implement the Itanium ABI unwinding base-API, and leave the
C++-specific parts to libcxxabi.

Co-authored-by: Lukas Wölfer <lukas.woelfer@rwth-aachen.de>
Diffstat (limited to 'test/CXX/symex/libc++/landingpad.cpp')
-rw-r--r--test/CXX/symex/libc++/landingpad.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/test/CXX/symex/libc++/landingpad.cpp b/test/CXX/symex/libc++/landingpad.cpp
new file mode 100644
index 00000000..21e55536
--- /dev/null
+++ b/test/CXX/symex/libc++/landingpad.cpp
@@ -0,0 +1,53 @@
+// Testcase for proper handling of
+// c++ type, constructors and destructors.
+// Based on: https://gcc.gnu.org/wiki/Dwarf2EHNewbiesHowto
+// REQUIRES: uclibc
+// REQUIRES: libcxx
+// RUN: %clangxx %s -emit-llvm %O0opt -std=c++11 -c -I "%libcxx_include" -g -nostdinc++ -o %t.bc
+// RUN: rm -rf %t.klee-out
+// RUN: %klee --output-dir=%t.klee-out --exit-on-error --libcxx --libc=uclibc  %t.bc | FileCheck %s
+// Expect the following output:
+// CHECK: Throwing 1...
+// CHECK: A() 1
+// CHECK: A(const A&) 2
+// CHECK: Caught.
+// CHECK: ~A() 2
+// CHECK: ~A() 1
+// CHECK: c == 2, d == 2
+
+#include <stdio.h>
+
+int c, d;
+
+struct A {
+  int i;
+  A() {
+    i = ++c;
+    printf("A() %d\n", i);
+  }
+  A(const A &) {
+    i = ++c;
+    printf("A(const A&) %d\n", i);
+  }
+  ~A() {
+    printf("~A() %d\n", i);
+    ++d;
+  }
+};
+
+void f() {
+  printf("Throwing 1...\n");
+  throw A();
+}
+
+int main() {
+  c = 0;
+  d = 0;
+  try {
+    f();
+  } catch (A) {
+    printf("Caught.\n");
+  }
+  printf("c == %d, d == %d\n", c, d);
+  return c != d;
+}