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
This commit is contained in:
Jonathan Wakely 2016-07-15 19:51:51 +01:00 committed by Jonathan Wakely
parent de54de93fa
commit 479d0ed590
5 changed files with 89 additions and 4 deletions

View File

@ -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.

View File

@ -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) {

View File

@ -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 ();
}

View File

@ -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.

View File

@ -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