This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/65610] [5 Regression] Compare debug failure with -g3 -fsanitize=undefined -fno-sanitize=vptr -O3


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

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I've tried:
--- gcc/ipa-polymorphic-call.c.jj    2015-03-09 08:05:06.000000000 +0100
+++ gcc/ipa-polymorphic-call.c    2015-03-30 11:24:48.280199943 +0200
@@ -513,6 +513,38 @@ contains_type_p (tree outer_type, HOST_W
 }


+/* Return a FUNCTION_DECL if BLOCK represents a constructor or destructor.
+   If CHECK_CLONES is true, also check for clones of ctor/dtors.  */
+
+tree
+ctor_dtor_block_p (tree block, bool check_clones)
+{
+  tree fn = BLOCK_ABSTRACT_ORIGIN (block);
+  if (fn == NULL || TREE_CODE (fn) != FUNCTION_DECL)
+    return NULL_TREE;
+
+  if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
+      || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
+    {
+      if (!check_clones)
+    return NULL_TREE;
+
+      /* Watch for clones where we constant propagated the first
+     argument (pointer to the instance).  */
+      fn = DECL_ABSTRACT_ORIGIN (fn);
+      if (!fn
+      || TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
+      || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
+    return NULL_TREE;
+    }
+
+  if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST))
+    return NULL_TREE;
+
+  return fn;
+}
+
+
 /* We know that the instance is stored in variable or parameter
    (not dynamically allocated) and we want to disprove the fact
    that it may be in construction at invocation of CALL.
@@ -552,28 +584,8 @@ decl_maybe_in_construction_p (tree base,

   for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
        block = BLOCK_SUPERCONTEXT (block))
-    if (BLOCK_ABSTRACT_ORIGIN (block)
-    && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block)) == FUNCTION_DECL)
+    if (tree fn = ctor_dtor_block_p (block, !base || is_global_var (base)))
       {
-    tree fn = BLOCK_ABSTRACT_ORIGIN (block);
-
-    if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
-        || (!DECL_CXX_CONSTRUCTOR_P (fn)
-        && !DECL_CXX_DESTRUCTOR_P (fn)))
-      {
-        /* Watch for clones where we constant propagated the first
-           argument (pointer to the instance).  */
-        fn = DECL_ABSTRACT_ORIGIN (fn);
-        if (!fn
-        || (base && !is_global_var (base))
-            || TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
-        || (!DECL_CXX_CONSTRUCTOR_P (fn)
-            && !DECL_CXX_DESTRUCTOR_P (fn)))
-          continue;
-      }
-    if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST))
-      continue;
-
     tree type = TYPE_MAIN_VARIANT (method_class_type (TREE_TYPE (fn)));

     if (!outer_type || !types_odr_comparable (type, outer_type))
@@ -1163,15 +1175,7 @@ noncall_stmt_may_be_vtbl_ptr_store (gimp
        block = BLOCK_SUPERCONTEXT (block))
     if (BLOCK_ABSTRACT_ORIGIN (block)
     && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block)) == FUNCTION_DECL)
-      {
-    tree fn = BLOCK_ABSTRACT_ORIGIN (block);
-
-    if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST))
-      return false;
-    return (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
-        && (DECL_CXX_CONSTRUCTOR_P (fn)
-            || DECL_CXX_DESTRUCTOR_P (fn)));
-      }
+      return ctor_dtor_block_p (block, false);
   return (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
       && (DECL_CXX_CONSTRUCTOR_P (current_function_decl)
           || DECL_CXX_DESTRUCTOR_P (current_function_decl)));

which I hope doesn't change ipa-polymorphic-call.c behavior,
but before adjusting remove_unused_scope_block_p to also do
else if (!cfun->after_inlining && ctor_dtor_block_p (scope, true))
  unused = false;
I've noticed that the noncall_stmt_may_be_vtbl_ptr_store call unfortunately
doesn't care just about the cdtor blocks, but about all blocks where
BLOCK_ABSTRACT_ORIGIN is a FUNCTION_DECL.
Preserving all such blocks would be too costly for -g0 I guess; wonder if we
e.g. could preserve in tree-ssa-live.c (!cfun->after_inlining ?) the
ctor_dtor_block_p (scope, true) and also pass a bool with the return of that
function down to the recursive remove_unused_scope_block_p calls and if that
flag is true, preserve the outermost scope with FUNCTION_DECL
block_abstract_origin there too.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]