Commit adf9c878 authored by Tom Stellard's avatar Tom Stellard
Browse files

Merging r236299:

------------------------------------------------------------------------
r236299 | ericwf | 2015-04-30 18:49:37 -0700 (Thu, 30 Apr 2015) | 7 lines

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

------------------------------------------------------------------------

llvm-svn: 236868
parent de42153e
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -381,9 +381,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<const __function_type_info*>(thrown_pointer_type->__pointee);
        return (thrown_function == nullptr);
    }
    // Handle pointer to pointer
    const __pointer_type_info* nested_pointer_type =
        dynamic_cast<const __pointer_type_info*>(__pointee);
+16 −0
Original line number Diff line number Diff line
@@ -11,11 +11,19 @@

#include <cassert>

template <class Tp>
bool can_convert(Tp) { return true; }

template <class>
bool can_convert(...) { return false; }

void f() {}

int main()
{
    typedef void Function();
    assert(!can_convert<Function&>(&f));
    assert(!can_convert<void*>(&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);
    }
}