aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2011-01-20 14:42:20 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2011-01-20 14:42:20 +0000
commit93e452edc601b55b9dab9f74327acebb8cd9fecf (patch)
tree0f55aae6dc629b463d8a9ea852a6aebef308a6ee /gcc
parent28fc44f389e4cf21f2d05312badde13b00ab25b6 (diff)
downloadgcc-93e452edc601b55b9dab9f74327acebb8cd9fecf.zip
gcc-93e452edc601b55b9dab9f74327acebb8cd9fecf.tar.gz
gcc-93e452edc601b55b9dab9f74327acebb8cd9fecf.tar.bz2
re PR middle-end/47370 (error: invalid first operand of MEM_REF)
2011-01-20 Richard Guenther <rguenther@suse.de> PR middle-end/47370 * tree-inline.c (remap_gimple_op_r): Recurse manually for the pointer operand of MEM_REFs. * gcc.dg/torture/pr47370.c: New testcase. From-SVN: r169055
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr47370.c27
-rw-r--r--gcc/tree-inline.c84
4 files changed, 75 insertions, 47 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 466579a..d7d4eb4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2011-01-20 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/47370
+ * tree-inline.c (remap_gimple_op_r): Recurse manually for
+ the pointer operand of MEM_REFs.
+
2011-01-20 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/46130
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c488050..336d1e5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-01-20 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/47370
+ * gcc.dg/torture/pr47370.c: New testcase.
+
2011-01-20 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/46130
diff --git a/gcc/testsuite/gcc.dg/torture/pr47370.c b/gcc/testsuite/gcc.dg/torture/pr47370.c
new file mode 100644
index 0000000..ff71f09
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr47370.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+
+struct S { int s; };
+
+void
+foo (void)
+{
+ for (;;)
+ ;
+}
+
+struct S
+bar (void)
+{
+ struct S s = { 99 };
+ return s;
+}
+
+void
+baz (int i)
+{
+ struct S s[1];
+ s[0] = bar ();
+ bar ();
+ foo ();
+}
+
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index c5ab4ca..24a6dd0 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -811,57 +811,47 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
knows not to copy VAR_DECLs, etc., so this is safe. */
if (TREE_CODE (*tp) == MEM_REF)
{
- /* We need to re-canonicalize MEM_REFs from inline substitutions
- that can happen when a pointer argument is an ADDR_EXPR. */
- tree decl = TREE_OPERAND (*tp, 0);
- tree *n;
-
- /* See remap_ssa_name. */
- if (TREE_CODE (decl) == SSA_NAME
- && TREE_CODE (SSA_NAME_VAR (decl)) == RESULT_DECL
- && id->transform_return_to_modify)
- decl = SSA_NAME_VAR (decl);
+ tree ptr = TREE_OPERAND (*tp, 0);
+ tree old = *tp;
+ tree tem;
- n = (tree *) pointer_map_contains (id->decl_map, decl);
- if (n)
+ /* We need to re-canonicalize MEM_REFs from inline substitutions
+ that can happen when a pointer argument is an ADDR_EXPR.
+ Recurse here manually to allow that. */
+ walk_tree (&ptr, remap_gimple_op_r, data, NULL);
+ if ((tem = maybe_fold_offset_to_reference (EXPR_LOCATION (*tp),
+ ptr,
+ TREE_OPERAND (*tp, 1),
+ TREE_TYPE (*tp)))
+ && TREE_THIS_VOLATILE (tem) == TREE_THIS_VOLATILE (old))
{
- tree old = *tp;
- tree ptr = unshare_expr (*n);
- tree tem;
- if ((tem = maybe_fold_offset_to_reference (EXPR_LOCATION (*tp),
- ptr,
- TREE_OPERAND (*tp, 1),
- TREE_TYPE (*tp)))
- && TREE_THIS_VOLATILE (tem) == TREE_THIS_VOLATILE (old))
- {
- tree *tem_basep = &tem;
- while (handled_component_p (*tem_basep))
- tem_basep = &TREE_OPERAND (*tem_basep, 0);
- if (TREE_CODE (*tem_basep) == MEM_REF)
- *tem_basep
- = build2 (MEM_REF, TREE_TYPE (*tem_basep),
- TREE_OPERAND (*tem_basep, 0),
- fold_convert (TREE_TYPE (TREE_OPERAND (*tp, 1)),
- TREE_OPERAND (*tem_basep, 1)));
- else
- *tem_basep
- = build2 (MEM_REF, TREE_TYPE (*tem_basep),
- build_fold_addr_expr (*tem_basep),
- build_int_cst
- (TREE_TYPE (TREE_OPERAND (*tp, 1)), 0));
- *tp = tem;
- }
+ tree *tem_basep = &tem;
+ while (handled_component_p (*tem_basep))
+ tem_basep = &TREE_OPERAND (*tem_basep, 0);
+ if (TREE_CODE (*tem_basep) == MEM_REF)
+ *tem_basep
+ = build2 (MEM_REF, TREE_TYPE (*tem_basep),
+ TREE_OPERAND (*tem_basep, 0),
+ fold_convert (TREE_TYPE (TREE_OPERAND (*tp, 1)),
+ TREE_OPERAND (*tem_basep, 1)));
else
- {
- *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
- ptr, TREE_OPERAND (*tp, 1));
- TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
- TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
- }
- TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
- *walk_subtrees = 0;
- return NULL;
+ *tem_basep
+ = build2 (MEM_REF, TREE_TYPE (*tem_basep),
+ build_fold_addr_expr (*tem_basep),
+ build_int_cst
+ (TREE_TYPE (TREE_OPERAND (*tp, 1)), 0));
+ *tp = tem;
}
+ else
+ {
+ *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
+ ptr, TREE_OPERAND (*tp, 1));
+ TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
+ TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
+ }
+ TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
+ *walk_subtrees = 0;
+ return NULL;
}
/* Here is the "usual case". Copy this tree node, and then