diff options
author | Marshall Clow <mclow.lists@gmail.com> | 2014-02-06 08:47:02 +0400 |
---|---|---|
committer | Marshall Clow <mclow.lists@gmail.com> | 2014-02-06 08:47:02 +0400 |
commit | d230a3d1f6df21caa8f48b4548c27e0f7a4dfbd1 (patch) | |
tree | 5950b8ce745af1ca3d5b6c7cf80b6a1b7ba079fc /libcxxabi/src/private_typeinfo.cpp | |
parent | bf71a34eb9e25c6080d5058a553dbcb75676ff95 (diff) |
Fix PR17221 - can't catch virtual base classes when throwing derived NULL pointers. Specifically, libc++abi would crash when you tried it.
llvm-svn: 200904
Diffstat (limited to 'libcxxabi/src/private_typeinfo.cpp')
-rw-r--r-- | libcxxabi/src/private_typeinfo.cpp | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/libcxxabi/src/private_typeinfo.cpp b/libcxxabi/src/private_typeinfo.cpp index 2dafdfb039cd..c65dcabdd632 100644 --- a/libcxxabi/src/private_typeinfo.cpp +++ b/libcxxabi/src/private_typeinfo.cpp @@ -301,17 +301,20 @@ __base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, void* adjustedPtr, int path_below) const { - ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; - if (__offset_flags & __virtual_mask) + ptrdiff_t offset_to_base = 0; + if (adjustedPtr != nullptr) { - const char* vtable = *static_cast<const char*const*>(adjustedPtr); - offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); + offset_to_base = __offset_flags >> __offset_shift; + if (__offset_flags & __virtual_mask) + { + const char* vtable = *static_cast<const char*const*>(adjustedPtr); + offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); + } } - __base_type->has_unambiguous_public_base(info, - static_cast<char*>(adjustedPtr) + offset_to_base, - (__offset_flags & __public_mask) ? - path_below : - not_public_path); + __base_type->has_unambiguous_public_base( + info, + static_cast<char*>(adjustedPtr) + offset_to_base, + (__offset_flags & __public_mask) ? path_below : not_public_path); } void @@ -358,7 +361,8 @@ __pointer_type_info::can_catch(const __shim_type_info* thrown_type, void*& adjustedPtr) const { // Do the dereference adjustment - adjustedPtr = *static_cast<void**>(adjustedPtr); + if (adjustedPtr != NULL) + adjustedPtr = *static_cast<void**>(adjustedPtr); // bullets 1 and 4 if (__pbase_type_info::can_catch(thrown_type, adjustedPtr)) return true; |