diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-09-18 12:34:43 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-09-18 12:34:43 +0000 |
commit | b42f9c368efa38da2ad4a405c31fc8b886fe438d (patch) | |
tree | fe6c5b9c31673294c79433d2e8dfa4e8007754b1 /libstdc++-v3 | |
parent | ca6c7c2e4af8538e0d46432b582d4b9e811990e9 (diff) | |
download | gcc-b42f9c368efa38da2ad4a405c31fc8b886fe438d.tar.gz |
* libsupc++/dyncast.cc (__dynamic_cast): Handle mid-destruction
dynamic_cast more gracefully.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@215350 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 5 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/dyncast.cc | 12 |
2 files changed, 17 insertions, 0 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2dc5a24d101..7682e279876 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,8 @@ +2014-09-17 Jason Merrill <jason@redhat.com> + + * libsupc++/dyncast.cc (__dynamic_cast): Handle mid-destruction + dynamic_cast more gracefully. + 2014-09-15 Jakub Jelinek <jakub@redhat.com> * testsuite/Makefile.am (check_p_numbers0, check_p_numbers1, diff --git a/libstdc++-v3/libsupc++/dyncast.cc b/libstdc++-v3/libsupc++/dyncast.cc index 2bcb7ddbd9c..9f6adeffcf2 100644 --- a/libstdc++-v3/libsupc++/dyncast.cc +++ b/libstdc++-v3/libsupc++/dyncast.cc @@ -55,6 +55,18 @@ __dynamic_cast (const void *src_ptr, // object started from adjust_pointer <void> (src_ptr, prefix->whole_object); const __class_type_info *whole_type = prefix->whole_type; __class_type_info::__dyncast_result result; + + // If the whole object vptr doesn't refer to the whole object type, we're + // in the middle of constructing a primary base, and src is a separate + // base. This has undefined behavior and we can't find anything outside + // of the base we're actually constructing, so fail now rather than + // segfault later trying to use a vbase offset that doesn't exist. + const void *whole_vtable = *static_cast <const void *const *> (whole_ptr); + const vtable_prefix *whole_prefix = + adjust_pointer <vtable_prefix> (whole_vtable, + -offsetof (vtable_prefix, origin)); + if (whole_prefix->whole_type != whole_type) + return NULL; whole_type->__do_dyncast (src2dst, __class_type_info::__contained_public, dst_type, whole_ptr, src_type, src_ptr, result); |