This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/65610] [5 Regression] Compare debug failure with -g3 -fsanitize=undefined -fno-sanitize=vptr -O3
- From: "jakub at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 30 Mar 2015 09:33:46 +0000
- Subject: [Bug tree-optimization/65610] [5 Regression] Compare debug failure with -g3 -fsanitize=undefined -fno-sanitize=vptr -O3
- Auto-submitted: auto-generated
- References: <bug-65610-4 at http dot gcc dot gnu dot org/bugzilla/>
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.