aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2016-07-15 19:51:51 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2016-07-15 19:51:51 +0100
commit479d0ed5900b8e87634cd92383c11a5571cc43d9 (patch)
tree84b1ce031651f5ab9047b20512bc2cacadc0912f
parentde54de93fa4bf4740638e58f9aaab1e50026bacb (diff)
downloadgcc-479d0ed5900b8e87634cd92383c11a5571cc43d9.zip
gcc-479d0ed5900b8e87634cd92383c11a5571cc43d9.tar.gz
gcc-479d0ed5900b8e87634cd92383c11a5571cc43d9.tar.bz2
c++/58796 Make nullptr match exception handlers of pointer type
libstdc++-v3: PR c++/58796 * libsupc++/pbase_type_info.cc (__pbase_type_info::__do_catch): Make nullptr match handlers of pointer type. gcc/testsuite: PR c++/58796 * g++.dg/cpp0x/nullptr21.C: Remove void* handlers. * g++.dg/cpp0x/nullptr35.C: New test. From-SVN: r238396
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nullptr21.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nullptr35.C52
-rw-r--r--libstdc++-v3/ChangeLog6
-rw-r--r--libstdc++-v3/libsupc++/pbase_type_info.cc25
5 files changed, 89 insertions, 4 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8a03901..305f96a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2016-07-15 Jonathan Wakely <jwakely@redhat.com>
+
+ PR c++/58796
+ * g++.dg/cpp0x/nullptr21.C: Remove void* handlers.
+ * g++.dg/cpp0x/nullptr35.C: New test.
+
2016-07-15 Bin Cheng <bin.cheng@arm.com>
* gcc.dg/tree-ssa/scev-8.c: Update test string.
diff --git a/gcc/testsuite/g++.dg/cpp0x/nullptr21.C b/gcc/testsuite/g++.dg/cpp0x/nullptr21.C
index 89884b9..c6f560e 100644
--- a/gcc/testsuite/g++.dg/cpp0x/nullptr21.C
+++ b/gcc/testsuite/g++.dg/cpp0x/nullptr21.C
@@ -18,8 +18,6 @@ int main()
{
try {
throw nullptr;
- } catch (void*) {
- foo (0, 1);
} catch (bool) {
foo (0, 2);
} catch (int) {
@@ -35,8 +33,6 @@ int main()
nullptr_t mynull = 0;
try {
throw mynull;
- } catch (void*) {
- foo (1, 1);
} catch (bool) {
foo (1, 2);
} catch (int) {
diff --git a/gcc/testsuite/g++.dg/cpp0x/nullptr35.C b/gcc/testsuite/g++.dg/cpp0x/nullptr35.C
new file mode 100644
index 0000000..2f93ce1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nullptr35.C
@@ -0,0 +1,52 @@
+// { dg-do run { target c++11 } }
+
+// Test catching as pointer and pointer to member types, [except.handle] p3.
+
+extern "C" void abort (void);
+
+typedef decltype(nullptr) nullptr_t;
+
+int result = 0;
+
+void __attribute__((noinline))
+caught(int bit)
+{
+ result &= bit;
+}
+
+struct A { };
+
+int main()
+{
+ try {
+ try {
+ try {
+ try {
+ try {
+ throw nullptr;
+ } catch (void* p) {
+ if (p == nullptr)
+ caught(1);
+ throw;
+ }
+ } catch (void(*pf)()) {
+ if (pf == nullptr)
+ caught(2);
+ throw;
+ }
+ } catch (int A::*pm) {
+ if (pm == nullptr)
+ caught(4);
+ throw;
+ }
+ } catch (int (A::*pmf)()) { // FIXME: currently unsupported
+ if (pmf == nullptr)
+ caught(8);
+ throw;
+ }
+ } catch (nullptr_t) {
+ }
+
+ if (result != 7) // should be 15
+ abort ();
+}
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 25b8191..3e4a0f5 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,9 @@
+2016-07-15 Jonathan Wakely <jwakely@redhat.com>
+
+ PR c++/58796
+ * libsupc++/pbase_type_info.cc (__pbase_type_info::__do_catch): Make
+ nullptr match handlers of pointer type.
+
2016-07-15 Edward Smith-Rowland <3dw4rd@verizon.net>
Implement C++17 P0025 clamp.
diff --git a/libstdc++-v3/libsupc++/pbase_type_info.cc b/libstdc++-v3/libsupc++/pbase_type_info.cc
index d47fb23..a2993e4 100644
--- a/libstdc++-v3/libsupc++/pbase_type_info.cc
+++ b/libstdc++-v3/libsupc++/pbase_type_info.cc
@@ -38,6 +38,31 @@ __do_catch (const type_info *thr_type,
return true; // same type
#if __cpp_rtti
+ if (*thr_type == typeid (nullptr))
+ {
+ // A catch handler for any pointer type matches nullptr_t.
+ if (typeid (*this) == typeid(__pointer_type_info))
+ {
+ *thr_obj = nullptr;
+ return true;
+ }
+ else if (typeid (*this) == typeid(__pointer_to_member_type_info))
+ {
+ if (__pointee->__is_function_p ())
+ {
+ // A pointer-to-member-function is two words <ptr,adj> but the
+ // nullptr_t exception object at *(nullptr_t*)*thr_obj is only
+ // one word, so we can't safely return it as a PMF. FIXME.
+ return false;
+ }
+ else
+ {
+ *(ptrdiff_t*)*thr_obj = -1; // null pointer to data member
+ return true;
+ }
+ }
+ }
+
if (typeid (*this) != typeid (*thr_type))
return false; // not both same kind of pointers
#endif