From b979db159a515fe12b54f793690618313e017259 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 1 May 2015 01:49:37 +0000 Subject: [PATCH] Disallow conversions from function pointers to void*. Function pointers and member function pointers cannot be converted to void*. libc++abi incorrectly allows this conversion for function pointers. Review URL: http://reviews.llvm.org/D8811 git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@236299 91177308-0d34-0410-b5e6-96231b3b80d8 --- src/private_typeinfo.cpp | 10 +++++++--- test/catch_function_01.pass.cpp | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/private_typeinfo.cpp b/src/private_typeinfo.cpp index 27aa704..beacd70 100644 --- a/src/private_typeinfo.cpp +++ b/src/private_typeinfo.cpp @@ -387,9 +387,13 @@ __pointer_type_info::can_catch(const __shim_type_info* thrown_type, if (is_equal(__pointee, thrown_pointer_type->__pointee, false)) return true; // bullet 3A - if (is_equal(__pointee, &typeid(void), false)) - return true; - + if (is_equal(__pointee, &typeid(void), false)) { + // pointers to functions cannot be converted to void*. + // pointers to member functions are not handled here. + const __function_type_info* thrown_function = + dynamic_cast(thrown_pointer_type->__pointee); + return (thrown_function == nullptr); + } // Handle pointer to pointer const __pointer_type_info* nested_pointer_type = dynamic_cast(__pointee); diff --git a/test/catch_function_01.pass.cpp b/test/catch_function_01.pass.cpp index 33999f2..087fce4 100644 --- a/test/catch_function_01.pass.cpp +++ b/test/catch_function_01.pass.cpp @@ -11,11 +11,19 @@ #include +template +bool can_convert(Tp) { return true; } + +template +bool can_convert(...) { return false; } + void f() {} int main() { typedef void Function(); + assert(!can_convert(&f)); + assert(!can_convert(&f)); try { throw f; // converts to void (*)() @@ -25,7 +33,15 @@ int main() { assert(false); } + catch (void*) // can't catch as void* + { + assert(false); + } + catch(Function*) + { + } catch (...) { + assert(false); } }