Add test case for inherited exceptions
authorJonathan Roelofs <jonathan@codesourcery.com>
Tue, 3 Jun 2014 21:50:11 +0000 (21:50 +0000)
committerJonathan Roelofs <jonathan@codesourcery.com>
Tue, 3 Jun 2014 21:50:11 +0000 (21:50 +0000)
Test case written by Dana Jansens.

llvm-svn: 210129

libcxxabi/test/inherited_exception.cpp [new file with mode: 0644]

diff --git a/libcxxabi/test/inherited_exception.cpp b/libcxxabi/test/inherited_exception.cpp
new file mode 100644 (file)
index 0000000..090ae97
--- /dev/null
@@ -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);
+    }
+}