summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0395-PR-c-49264.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0395-PR-c-49264.patch')
-rw-r--r--meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0395-PR-c-49264.patch134
1 files changed, 134 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0395-PR-c-49264.patch b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0395-PR-c-49264.patch
new file mode 100644
index 0000000000..eab6abedb3
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0395-PR-c-49264.patch
@@ -0,0 +1,134 @@
1From 90eb3072e3353e49d60c903664b2e9e2efc5d1de Mon Sep 17 00:00:00 2001
2From: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
3Date: Mon, 6 Jun 2011 17:16:35 +0000
4Subject: [PATCH] PR c++/49264
5 * gimple-fold.c (fold_stmt_1): Don't try to fold *& on the lhs
6 if stmt folded into nothing.
7 * tree-inline.c (fold_marked_statements): If a builtin at the
8 end of a bb folded into nothing, just update cgraph edges
9 and move to next bb.
10 * cgraph.c (cgraph_update_edges_for_call_stmt_node): Allow new_stmt
11 to be NULL. Don't compute count and frequency if new_call is NULL.
12
13 * g++.dg/opt/pr49264.C: New test.
14
15
16git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@174713 138bc75d-0d04-0410-961f-82ee72b054a4
17
18index 64d278f..41265f8 100644
19--- a/gcc/cgraph.c
20+++ b/gcc/cgraph.c
21@@ -1241,13 +1241,17 @@ cgraph_make_edge_direct (struct cgraph_edge *edge, struct cgraph_node *callee,
22
23 /* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
24 OLD_STMT changed into NEW_STMT. OLD_CALL is gimple_call_fndecl
25- of OLD_STMT if it was previously call statement. */
26+ of OLD_STMT if it was previously call statement.
27+ If NEW_STMT is NULL, the call has been dropped without any
28+ replacement. */
29
30 static void
31 cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
32- gimple old_stmt, tree old_call, gimple new_stmt)
33+ gimple old_stmt, tree old_call,
34+ gimple new_stmt)
35 {
36- tree new_call = (is_gimple_call (new_stmt)) ? gimple_call_fndecl (new_stmt) : 0;
37+ tree new_call = (new_stmt && is_gimple_call (new_stmt))
38+ ? gimple_call_fndecl (new_stmt) : 0;
39
40 /* We are seeing indirect calls, then there is nothing to update. */
41 if (!new_call && !old_call)
42@@ -1287,7 +1291,7 @@ cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
43 loop_nest = e->loop_nest;
44 cgraph_remove_edge (e);
45 }
46- else
47+ else if (new_call)
48 {
49 /* We are seeing new direct call; compute profile info based on BB. */
50 basic_block bb = gimple_bb (new_stmt);
51diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
52index 910e3b0..cd8f409 100644
53--- a/gcc/gimple-fold.c
54+++ b/gcc/gimple-fold.c
55@@ -1484,6 +1484,11 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
56 bool changed = false;
57 gimple stmt = gsi_stmt (*gsi);
58 unsigned i;
59+ gimple_stmt_iterator gsinext = *gsi;
60+ gimple next_stmt;
61+
62+ gsi_next (&gsinext);
63+ next_stmt = gsi_end_p (gsinext) ? NULL : gsi_stmt (gsinext);
64
65 /* Fold the main computation performed by the statement. */
66 switch (gimple_code (stmt))
67@@ -1572,10 +1577,19 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
68 default:;
69 }
70
71+ /* If stmt folds into nothing and it was the last stmt in a bb,
72+ don't call gsi_stmt. */
73+ if (gsi_end_p (*gsi))
74+ {
75+ gcc_assert (next_stmt == NULL);
76+ return changed;
77+ }
78+
79 stmt = gsi_stmt (*gsi);
80
81- /* Fold *& on the lhs. */
82- if (gimple_has_lhs (stmt))
83+ /* Fold *& on the lhs. Don't do this if stmt folded into nothing,
84+ as we'd changing the next stmt. */
85+ if (gimple_has_lhs (stmt) && stmt != next_stmt)
86 {
87 tree lhs = gimple_get_lhs (stmt);
88 if (lhs && REFERENCE_CLASS_P (lhs))
89new file mode 100644
90index 0000000..dc23740
91--- /dev/null
92+++ b/gcc/testsuite/g++.dg/opt/pr49264.C
93@@ -0,0 +1,19 @@
94+// PR c++/49264
95+// { dg-do compile }
96+// { dg-options "-O2" }
97+
98+struct B { };
99+struct A { char a[sizeof (B) + 1]; } a;
100+
101+static inline void
102+foo (const B &b)
103+{
104+ __builtin_memcpy (&a, &b, sizeof (b));
105+}
106+
107+void
108+bar ()
109+{
110+ B c;
111+ foo (c);
112+}
113diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
114index ef3f1a3..a0162de 100644
115--- a/gcc/tree-inline.c
116+++ b/gcc/tree-inline.c
117@@ -4117,6 +4117,14 @@ fold_marked_statements (int first, struct pointer_set_t *statements)
118 if (fold_stmt (&gsi))
119 {
120 gimple new_stmt;
121+ /* If a builtin at the end of a bb folded into nothing,
122+ the following loop won't work. */
123+ if (gsi_end_p (gsi))
124+ {
125+ cgraph_update_edges_for_call_stmt (old_stmt,
126+ old_decl, NULL);
127+ break;
128+ }
129 if (gsi_end_p (i2))
130 i2 = gsi_start_bb (BASIC_BLOCK (first));
131 else
132--
1331.7.0.4
134