aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/ipa-inline.c7
-rw-r--r--gcc/ipa-prop.c4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr46367.C11
5 files changed, 34 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1eab500..3624c0d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2011-01-07 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/46367
+ * ipa-inline.c (cgraph_clone_inlined_nodes): Use original function only
+ when we can update original.
+ (cgraph_mark_inline_edge): Sanity check.
+ * ipa-prop.c (ipa_make_edge_direct_to_target): Sanity check.
+
2011-01-07 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* config/spu/spu.h (ASM_COMMENT_START): Define.
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 7ac50dd..116abd6 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -232,6 +232,8 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
/* We may eliminate the need for out-of-line copy to be output.
In that case just go ahead and re-use it. */
if (!e->callee->callers->next_caller
+ /* Recursive inlining never wants the master clone to be overwritten. */
+ && update_original
/* FIXME: When address is taken of DECL_EXTERNAL function we still can remove its
offline copy, but we would need to keep unanalyzed node in the callgraph so
references can point to it. */
@@ -303,7 +305,11 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original,
struct cgraph_edge *curr = e;
int freq;
+ /* Don't inline inlined edges. */
gcc_assert (e->inline_failed);
+ /* Don't even think of inlining inline clone. */
+ gcc_assert (!e->callee->global.inlined_to);
+
e->inline_failed = CIF_OK;
DECL_POSSIBLY_INLINED (e->callee->decl) = true;
@@ -863,7 +869,6 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node,
master_clone = cgraph_clone_node (node, node->decl,
node->count, CGRAPH_FREQ_BASE, 1,
false, NULL);
- master_clone->needed = true;
for (e = master_clone->callees; e; e = e->next_callee)
if (!e->inline_failed)
cgraph_clone_inlined_nodes (e, true, false);
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index f85a4ff..106fc23 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1483,6 +1483,10 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target, tree delta)
return NULL;
ipa_check_create_node_params ();
+ /* We can not make edges to inline clones. It is bug that someone removed the cgraph
+ node too early. */
+ gcc_assert (!callee->global.inlined_to);
+
cgraph_make_edge_direct (ie, callee, delta ? tree_low_cst (delta, 0) : 0);
if (dump_file)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 286bbcf..e91432e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-01-07 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/46367
+ * g++.dg/torture/pr46367.C: New file.
+
2011-01-07 Jakub Jelinek <jakub@redhat.com>
PR target/47201
diff --git a/gcc/testsuite/g++.dg/torture/pr46367.C b/gcc/testsuite/g++.dg/torture/pr46367.C
new file mode 100644
index 0000000..260b5c1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr46367.C
@@ -0,0 +1,11 @@
+#pragma interface
+struct S
+{
+ S *s;
+ ~S ()
+ {
+ delete s;
+ }
+};
+
+S s;