aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-08-13 19:06:13 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2013-08-13 19:06:13 +0200
commit4029a5e06387a5d222a4a7ff870404678b0054c0 (patch)
treed5c18123e7a057448dfc5369c00a76ff6e121643 /gcc
parent99c2bd544a3f84ae1716a0d8d973c98fc0534f86 (diff)
downloadgcc-4029a5e06387a5d222a4a7ff870404678b0054c0.zip
gcc-4029a5e06387a5d222a4a7ff870404678b0054c0.tar.gz
gcc-4029a5e06387a5d222a4a7ff870404678b0054c0.tar.bz2
re PR middle-end/57661 (ICE: SIGSEGV in verify_ssa)
PR tree-optimization/57661 * tree-inline.h (struct copy_body_data): Add blocks_to_copy field. * tree-inline.c (tree_function_versioning): Initialize it. (remap_gimple_stmt): Return GIMPLE_NOP for MEM_REF lhs clobber stmts if id->blocks_to_copy and MEM_REF's SSA_NAME is defined in a block that is not being copied. * g++.dg/opt/pr57661.C: New test. From-SVN: r201698
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/opt/pr57661.C76
-rw-r--r--gcc/tree-inline.c18
-rw-r--r--gcc/tree-inline.h4
5 files changed, 108 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 682328e..f22f848 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2013-08-13 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/57661
+ * tree-inline.h (struct copy_body_data): Add blocks_to_copy field.
+ * tree-inline.c (tree_function_versioning): Initialize it.
+ (remap_gimple_stmt): Return GIMPLE_NOP for MEM_REF lhs clobber stmts
+ if id->blocks_to_copy and MEM_REF's SSA_NAME is defined in a block
+ that is not being copied.
+
PR sanitizer/56417
* asan.c (instrument_strlen_call): Fix typo in comment.
Use char * type even for the lhs of POINTER_PLUS_EXPR.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6e1b630..f962249 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2013-08-13 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/57661
+ * g++.dg/opt/pr57661.C: New test.
+
PR sanitizer/56417
* gcc.dg/asan/pr56417.c: New test.
diff --git a/gcc/testsuite/g++.dg/opt/pr57661.C b/gcc/testsuite/g++.dg/opt/pr57661.C
new file mode 100644
index 0000000..8be9f09
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr57661.C
@@ -0,0 +1,76 @@
+// PR tree-optimization/57661
+// { dg-do compile }
+// { dg-options "-O2 -fno-tree-forwprop -std=gnu++11" }
+
+template <typename>
+struct A
+{
+ ~A () {}
+};
+template <typename _Tp>
+using B = A <_Tp>;
+template <typename _Tp>
+class C : B <_Tp> {};
+namespace N { enum D { d }; }
+template <class>
+struct E
+{
+ ~E ();
+};
+template <class, class V>
+struct F : V {};
+template <class U, class V>
+struct G : F <U, V>
+{
+ N::D g1;
+ void g2 ();
+ void g3 ();
+ void g4 () { g3 (); }
+ static void g5 (G *__t) { __t->g4 (); }
+};
+template <class U, class V>
+struct H : G <U, V>
+{
+ E <U> *h1;
+ bool h2;
+ ~H () throw ()
+ {
+ this->g2 ();
+ if (h2)
+ delete h1;
+ }
+};
+template <class U, class V>
+struct I : H <U, V>, E <U>
+{
+ G <U, V> *i;
+ ~I () throw ()
+ {
+ i->g4 ();
+ }
+};
+struct J
+{
+ typedef C <char> j1;
+ typedef G <char, C <char>> j2;
+ J ();
+ j2 *j3;
+};
+struct K : J
+{
+ typedef G <char, C <char>> j2;
+ K () { j2::g5 (this->j3); }
+};
+template <class U, class V>
+void G <U, V>::g3 ()
+{
+ switch (g1)
+ {
+ case N::d:
+ {
+ I <U, V> *q = (I <U, V> *) this;
+ q->I <U, V>::~I ();
+ }
+ }
+}
+K r;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 00e3198..55e5270 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1387,6 +1387,23 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
}
}
+ /* For *ptr_N ={v} {CLOBBER}, if ptr_N is SSA_NAME defined
+ in a block that we aren't copying during tree_function_versioning,
+ just drop the clobber stmt. */
+ if (id->blocks_to_copy && gimple_clobber_p (stmt))
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ if (TREE_CODE (lhs) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME)
+ {
+ gimple def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (lhs, 0));
+ if (gimple_bb (def_stmt)
+ && !bitmap_bit_p (id->blocks_to_copy,
+ gimple_bb (def_stmt)->index))
+ return gimple_build_nop ();
+ }
+ }
+
if (gimple_debug_bind_p (stmt))
{
copy = gimple_build_debug_bind (gimple_debug_bind_get_var (stmt),
@@ -5161,6 +5178,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
id.src_node = old_version_node;
id.dst_node = new_version_node;
id.src_cfun = DECL_STRUCT_FUNCTION (old_decl);
+ id.blocks_to_copy = blocks_to_copy;
if (id.src_node->ipa_transforms_to_apply.exists ())
{
vec<ipa_opt_pass> old_transforms_to_apply
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index b65dee9..620ec97 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -115,6 +115,10 @@ typedef struct copy_body_data
/* Entry basic block to currently copied body. */
basic_block entry_bb;
+ /* For partial function versioning, bitmap of bbs to be copied,
+ otherwise NULL. */
+ bitmap blocks_to_copy;
+
/* Debug statements that need processing. */
vec<gimple> debug_stmts;