Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarshall Clow <mclow.lists@gmail.com>2014-02-06 08:47:02 +0400
committerMarshall Clow <mclow.lists@gmail.com>2014-02-06 08:47:02 +0400
commitd230a3d1f6df21caa8f48b4548c27e0f7a4dfbd1 (patch)
tree5950b8ce745af1ca3d5b6c7cf80b6a1b7ba079fc /libcxxabi/src/private_typeinfo.cpp
parentbf71a34eb9e25c6080d5058a553dbcb75676ff95 (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.cpp24
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;