summaryrefslogtreecommitdiff
path: root/test/catch_reference_nullptr.pass.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-07-19 20:19:37 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-07-19 20:19:37 +0000
commit081ea86d80df60bcbb5517868ec5f1afab6bf973 (patch)
tree09943f2017e8e7b3457914f3541c4e81b1bddee9 /test/catch_reference_nullptr.pass.cpp
parente8b3ec33ccb6f76caea7388317d5620b9c36de51 (diff)
[libcxxabi] When catching an exception of type nullptr_t with a handler of
pointer-to-member type, produce a null value of the right type. This fixes a bug where throwing an exception of type nullptr_t and catching it as a pointer-to-member would not guarantee to produce a null value in the catch handler. The fix is pretty simple: we statically allocate a constant null pointer-to-data-member representation and a constant null pointer-to-member-function representation, and produce the address of the relevant value as the adjusted pointer for the exception. git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@276016 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/catch_reference_nullptr.pass.cpp')
-rw-r--r--test/catch_reference_nullptr.pass.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/test/catch_reference_nullptr.pass.cpp b/test/catch_reference_nullptr.pass.cpp
new file mode 100644
index 0000000..0e7955f
--- /dev/null
+++ b/test/catch_reference_nullptr.pass.cpp
@@ -0,0 +1,49 @@
+//===--------------------- catch_pointer_nullptr.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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, libcxxabi-no-exceptions
+
+#include <cassert>
+#include <cstdlib>
+
+struct A {};
+
+template<typename T, bool CanCatchNullptr>
+static void catch_nullptr_test() {
+ try {
+ throw nullptr;
+ } catch (T &p) {
+ assert(CanCatchNullptr && !p);
+ } catch (...) {
+ assert(!CanCatchNullptr);
+ }
+}
+
+int main()
+{
+ using nullptr_t = decltype(nullptr);
+
+ // A reference to nullptr_t can catch nullptr.
+ catch_nullptr_test<nullptr_t, true>();
+ catch_nullptr_test<const nullptr_t, true>();
+ catch_nullptr_test<volatile nullptr_t, true>();
+ catch_nullptr_test<const volatile nullptr_t, true>();
+
+ // No other reference type can.
+#if 0
+ // FIXME: These tests fail, because the ABI provides no way for us to
+ // distinguish this from catching by value.
+ catch_nullptr_test<void *, false>();
+ catch_nullptr_test<void * const, false>();
+ catch_nullptr_test<int *, false>();
+ catch_nullptr_test<A *, false>();
+ catch_nullptr_test<int A::*, false>();
+ catch_nullptr_test<int (A::*)(), false>();
+#endif
+}