diff options
author | Eric Fiselier <eric@efcs.ca> | 2018-05-18 20:51:38 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2018-05-18 20:51:38 +0000 |
commit | 29e02657322f0cdfaefce0ae2d29f3e02ba0a3cc (patch) | |
tree | 9ba950f419b5c688467e46279ee9b1c41553d094 /libcxxabi/src | |
parent | 401b5ecfeaa014b2c420c5419e5e2edfe2e56390 (diff) | |
download | bcm5719-llvm-29e02657322f0cdfaefce0ae2d29f3e02ba0a3cc.tar.gz bcm5719-llvm-29e02657322f0cdfaefce0ae2d29f3e02ba0a3cc.zip |
private_typeinfo: limit is_dst_type_derived_from_static_type optimization
Patch by Ryan Prichard
If the destination type does not derive from the static type, we can skip
the search_above_dst call, but we still need to run the
!does_dst_type_point_to_our_static_type block of code. That block of code
will increment info->number_to_dst_ptr to 2, and because dest isn't derived
from static, the cast will ultimately fail.
Fixes PR33439
Reviewed as https://reviews.llvm.org/D36447
llvm-svn: 332767
Diffstat (limited to 'libcxxabi/src')
-rw-r--r-- | libcxxabi/src/private_typeinfo.cpp | 65 |
1 files changed, 33 insertions, 32 deletions
diff --git a/libcxxabi/src/private_typeinfo.cpp b/libcxxabi/src/private_typeinfo.cpp index 6da3c779c3b..a0326a188c4 100644 --- a/libcxxabi/src/private_typeinfo.cpp +++ b/libcxxabi/src/private_typeinfo.cpp @@ -859,13 +859,14 @@ __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, // Record the access path that got us here // If there is more than one dst_type this path doesn't matter. info->path_dynamic_ptr_to_dst_ptr = path_below; + bool does_dst_type_point_to_our_static_type = false; // Only search above here if dst_type derives from static_type, or // if it is unknown if dst_type derives from static_type. if (info->is_dst_type_derived_from_static_type != no) { // Set up flags to record results from all base classes bool is_dst_type_derived_from_static_type = false; - bool does_dst_type_point_to_our_static_type = false; + // We've found a dst_type with a potentially public path to here. // We have to assume the path is public because it may become // public later (if we get back to here with a public path). @@ -909,21 +910,6 @@ __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, } } } - if (!does_dst_type_point_to_our_static_type) - { - // We found a dst_type that doesn't point to (static_ptr, static_type) - // So record the address of this dst_ptr and increment the - // count of the number of such dst_types found in the tree. - info->dst_ptr_not_leading_to_static_ptr = current_ptr; - info->number_to_dst_ptr += 1; - // If there exists another dst with a private path to - // (static_ptr, static_type), then the cast from - // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous, - // so stop search. - if (info->number_to_static_ptr == 1 && - info->path_dst_ptr_to_static_ptr == not_public_path) - info->search_done = true; - } // If we found no static_type,s then dst_type doesn't derive // from static_type, else it does. Record this result so that // next time we hit a dst_type we will know not to search above @@ -932,7 +918,22 @@ __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, info->is_dst_type_derived_from_static_type = yes; else info->is_dst_type_derived_from_static_type = no; - } + } + if (!does_dst_type_point_to_our_static_type) + { + // We found a dst_type that doesn't point to (static_ptr, static_type) + // So record the address of this dst_ptr and increment the + // count of the number of such dst_types found in the tree. + info->dst_ptr_not_leading_to_static_ptr = current_ptr; + info->number_to_dst_ptr += 1; + // If there exists another dst with a private path to + // (static_ptr, static_type), then the cast from + // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous, + // so stop search. + if (info->number_to_static_ptr == 1 && + info->path_dst_ptr_to_static_ptr == not_public_path) + info->search_done = true; + } } } else @@ -1030,13 +1031,13 @@ __si_class_type_info::search_below_dst(__dynamic_cast_info* info, // Record the access path that got us here // If there is more than one dst_type this path doesn't matter. info->path_dynamic_ptr_to_dst_ptr = path_below; + bool does_dst_type_point_to_our_static_type = false; // Only search above here if dst_type derives from static_type, or // if it is unknown if dst_type derives from static_type. if (info->is_dst_type_derived_from_static_type != no) { // Set up flags to record results from all base classes bool is_dst_type_derived_from_static_type = false; - bool does_dst_type_point_to_our_static_type = false; // Zero out found flags info->found_our_static_ptr = false; info->found_any_static_type = false; @@ -1047,20 +1048,6 @@ __si_class_type_info::search_below_dst(__dynamic_cast_info* info, if (info->found_our_static_ptr) does_dst_type_point_to_our_static_type = true; } - if (!does_dst_type_point_to_our_static_type) - { - // We found a dst_type that doesn't point to (static_ptr, static_type) - // So record the address of this dst_ptr and increment the - // count of the number of such dst_types found in the tree. - info->dst_ptr_not_leading_to_static_ptr = current_ptr; - info->number_to_dst_ptr += 1; - // If there exists another dst with a private path to - // (static_ptr, static_type), then the cast from - // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous. - if (info->number_to_static_ptr == 1 && - info->path_dst_ptr_to_static_ptr == not_public_path) - info->search_done = true; - } // If we found no static_type,s then dst_type doesn't derive // from static_type, else it does. Record this result so that // next time we hit a dst_type we will know not to search above @@ -1070,6 +1057,20 @@ __si_class_type_info::search_below_dst(__dynamic_cast_info* info, else info->is_dst_type_derived_from_static_type = no; } + if (!does_dst_type_point_to_our_static_type) + { + // We found a dst_type that doesn't point to (static_ptr, static_type) + // So record the address of this dst_ptr and increment the + // count of the number of such dst_types found in the tree. + info->dst_ptr_not_leading_to_static_ptr = current_ptr; + info->number_to_dst_ptr += 1; + // If there exists another dst with a private path to + // (static_ptr, static_type), then the cast from + // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous. + if (info->number_to_static_ptr == 1 && + info->path_dst_ptr_to_static_ptr == not_public_path) + info->search_done = true; + } } } else |