summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Roelofs <jonathan@codesourcery.com>2014-06-03 21:50:11 +0000
committerJonathan Roelofs <jonathan@codesourcery.com>2014-06-03 21:50:11 +0000
commite53a8f3242d02744c4f634abc3504d3b34302930 (patch)
treef4577765045cd54672485f64446a31ed6015921a
parent13584a6f4156e220d037340a8265e971125fd3ef (diff)
Add test case for inherited exceptions
Test case written by Dana Jansens. git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@210129 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--test/inherited_exception.cpp165
1 files changed, 165 insertions, 0 deletions
diff --git a/test/inherited_exception.cpp b/test/inherited_exception.cpp
new file mode 100644
index 0000000..090ae97
--- /dev/null
+++ b/test/inherited_exception.cpp
@@ -0,0 +1,165 @@
+//===--------------------- inherited_exception.cpp ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This test case checks specifically the cases under C++ ABI 15.3.1, and 15.3.2
+//
+// C++ ABI 15.3:
+// A handler is a match for an exception object of type E if
+// / * The handler is of type cv T or cv T& and E and T are the same type \
+// | (ignoring the top-level cv-qualifiers), or |
+// | * the handler is of type cv T or cv T& and T is an unambiguous base |
+// \ class of E, or /
+// * the handler is of type cv1 T* cv2 and E is a pointer type that can
+// be converted to the type of the handler by either or both of
+// o a standard pointer conversion (4.10 [conv.ptr]) not involving
+// conversions to private or protected or ambiguous classes
+// o a qualification conversion
+// * the handler is a pointer or pointer to member type and E is
+// std::nullptr_t
+//
+//===----------------------------------------------------------------------===//
+
+#include <assert.h>
+
+struct Base {
+ int b1;
+};
+
+struct Base2 {
+ int b2;
+};
+
+struct Child : public Base, public Base2 {
+ int c;
+};
+
+void f1() {
+ Child child;
+ child.b1 = 10;
+ child.b2 = 11;
+ child.c = 12;
+ throw child;
+}
+
+void f2() {
+ Child child;
+ child.b1 = 10;
+ child.b2 = 11;
+ child.c = 12;
+ throw static_cast<Base2&>(child);
+}
+
+void f3() {
+ Child* child = new Child;
+ child->b1 = 10;
+ child->b2 = 11;
+ child->c = 12;
+ throw static_cast<Base2*>(child);
+}
+
+int main()
+{
+ try
+ {
+ f1();
+ assert(false);
+ }
+ catch (const Child& c)
+ {
+ assert(true);
+ }
+ catch (const Base& b)
+ {
+ assert(false);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+
+ try
+ {
+ f1();
+ assert(false);
+ }
+ catch (const Base& c)
+ {
+ assert(true);
+ }
+ catch (const Child& b)
+ {
+ assert(false);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+
+ try
+ {
+ f1();
+ assert(false);
+ }
+ catch (const Base2& c)
+ {
+ assert(true);
+ }
+ catch (const Child& b)
+ {
+ assert(false);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+
+ try
+ {
+ f2();
+ assert(false);
+ }
+ catch (const Child& c)
+ {
+ assert(false);
+ }
+ catch (const Base& b)
+ {
+ assert(false);
+ }
+ catch (const Base2& b)
+ {
+ assert(true);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+
+ try
+ {
+ f3();
+ assert(false);
+ }
+ catch (const Base* c)
+ {
+ assert(false);
+ }
+ catch (const Child* b)
+ {
+ assert(false);
+ }
+ catch (const Base2* c)
+ {
+ assert(true);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+}