[Bug ipa/101839] [10/11/12/13 Regression] Hang in C++ code with -fdevirtualize

yinyuefengyi at gmail dot com gcc-bugzilla@gcc.gnu.org
Wed Aug 10 03:53:45 GMT 2022


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101839

--- Comment #8 from Xionghu Luo (luoxhu at gcc dot gnu.org) <yinyuefengyi at gmail dot com> ---
The relationship is:

A  A::type
| ------------
|             |
BA BA::type   CA    CA::type
|
CBA CBA::type

class CA and CBA are final, also function CA::type and BA::type are final, then
in function possible_polymorphic_call_targets for "target" BA::type, the
"DECL_FINAL_P (target)" check is not accurate enough, as there may be classes
like CBA derived from BA and have instance that need continue walk recursively
in possible_polymorphic_call_targets_1 to record_target_from_binfo.

      if (target)
        {
          /* In the case we get complete method, we don't need 
             to walk derivations.  */
          if (DECL_FINAL_P (target))
            context.maybe_derived_type = false;
        }

So fix this by belong change only stop walk derivations when target is final
and it's class outer_type->type is also final?

diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc
index 412ca14f66b..77f9b268e86 100644
--- a/gcc/ipa-devirt.cc
+++ b/gcc/ipa-devirt.cc
@@ -3188,7 +3188,9 @@ possible_polymorphic_call_targets (tree otr_type,

       /* In the case we get complete method, we don't need
         to walk derivations.  */
-      if (target && DECL_FINAL_P (target))
+      if (target && TREE_CODE (target) == FUNCTION_DECL && DECL_FINAL_P
(target)
+         && RECORD_OR_UNION_TYPE_P (out er_type->type)
+         && TYPE_FINAL_P (outer_type->type))
        context.speculative_maybe_derived_type = false;
       if (type_possibly_instantiated_p (speculative_outer_type->type))
        maybe_record_node (nodes, target, &inserted, can_refer,
&speculation_complete);
@@ -3233,7 +3235,9 @@ possible_polymorphic_call_targets (tree otr_type,
        {
          /* In the case we get complete method, we don't need
             to walk derivations.  */
-         if (DECL_FINAL_P (target))
+         if (TREE_CODE (target) == FUNCTION_DECL && DECL_FINAL_P (target)
+             && RECORD_OR_UNION_TYPE_P (outer_type->type)
+             && TYPE_FINAL_P (outer_type->type))
            context.maybe_derived_type = false;
        }


More information about the Gcc-bugs mailing list