aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-live.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2015-03-30 23:56:02 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2015-03-30 23:56:02 +0200
commit00a0ea64eec42da418a111bb4585b2ea007358dc (patch)
tree4a2145b3fd570aa231e78ea5f2d8819866f798a9 /gcc/tree-ssa-live.c
parentef4bac7802534e52d3031dccf0cdfb2c53b2d836 (diff)
downloadgcc-00a0ea64eec42da418a111bb4585b2ea007358dc.zip
gcc-00a0ea64eec42da418a111bb4585b2ea007358dc.tar.gz
gcc-00a0ea64eec42da418a111bb4585b2ea007358dc.tar.bz2
re PR ipa/65610 (Compare debug failure with -g3 -fsanitize=undefined -fno-sanitize=vptr -O3)
PR ipa/65610 * ipa-utils.h (inlined_polymorphic_ctor_dtor_block_p): Declare. * ipa-polymorphic-call.c (inlined_polymorphic_ctor_dtor_block_p): New function. (decl_maybe_in_construction_p, noncall_stmt_may_be_vtbl_ptr_store): Use it. * ipa-prop.c (param_type_may_change_p): Likewise. * tree-ssa-live.c: Include ipa-utils.h and its dependencies. (remove_unused_scope_block_p): Add in_ctor_dtor_block argument. Before inlining, preserve inlined_polymorphic_ctor_dtor_block_p blocks and the outermost block with FUNCTION_DECL BLOCK_ABSTRACT_ORIGIN inside of them. Adjust recursive calls. (remove_unused_locals): Adjust remove_unused_scope_block_p caller. * g++.dg/ubsan/pr65610.C: New test. From-SVN: r221781
Diffstat (limited to 'gcc/tree-ssa-live.c')
-rw-r--r--gcc/tree-ssa-live.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index e0c42669..df90229 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -76,6 +76,10 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "debug.h"
#include "tree-ssa.h"
+#include "lto-streamer.h"
+#include "ipa-ref.h"
+#include "cgraph.h"
+#include "ipa-utils.h"
#ifdef ENABLE_CHECKING
static void verify_live_on_entry (tree_live_info_p);
@@ -509,12 +513,29 @@ mark_scope_block_unused (tree scope)
done by the inliner. */
static bool
-remove_unused_scope_block_p (tree scope)
+remove_unused_scope_block_p (tree scope, bool in_ctor_dtor_block)
{
tree *t, *next;
bool unused = !TREE_USED (scope);
int nsubblocks = 0;
+ /* For ipa-polymorphic-call.c purposes, preserve blocks:
+ 1) with BLOCK_ABSTRACT_ORIGIN of a ctor/dtor or their clones */
+ if (inlined_polymorphic_ctor_dtor_block_p (scope, true))
+ {
+ in_ctor_dtor_block = true;
+ unused = false;
+ }
+ /* 2) inside such blocks, the outermost block with BLOCK_ABSTRACT_ORIGIN
+ being a FUNCTION_DECL. */
+ else if (in_ctor_dtor_block
+ && BLOCK_ABSTRACT_ORIGIN (scope)
+ && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (scope)) == FUNCTION_DECL)
+ {
+ in_ctor_dtor_block = false;
+ unused = false;
+ }
+
for (t = &BLOCK_VARS (scope); *t; t = next)
{
next = &DECL_CHAIN (*t);
@@ -594,7 +615,7 @@ remove_unused_scope_block_p (tree scope)
}
for (t = &BLOCK_SUBBLOCKS (scope); *t ;)
- if (remove_unused_scope_block_p (*t))
+ if (remove_unused_scope_block_p (*t, in_ctor_dtor_block))
{
if (BLOCK_SUBBLOCKS (*t))
{
@@ -959,7 +980,7 @@ remove_unused_locals (void)
cfun->local_decls->truncate (dstidx);
}
- remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
+ remove_unused_scope_block_p (DECL_INITIAL (current_function_decl), false);
clear_unused_block_pointer ();
BITMAP_FREE (usedvars);