From 93e452edc601b55b9dab9f74327acebb8cd9fecf Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Thu, 20 Jan 2011 14:42:20 +0000 Subject: [PATCH] re PR middle-end/47370 (error: invalid first operand of MEM_REF) 2011-01-20 Richard Guenther 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 --- gcc/ChangeLog | 6 ++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/torture/pr47370.c | 27 +++++++++ gcc/tree-inline.c | 84 ++++++++++++-------------- 4 files changed, 75 insertions(+), 47 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr47370.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 466579a1792..d7d4eb485bd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-01-20 Richard Guenther + + 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 PR tree-optimization/46130 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c4880506aec..336d1e58faf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-01-20 Richard Guenther + + PR middle-end/47370 + * gcc.dg/torture/pr47370.c: New testcase. + 2011-01-20 Jakub Jelinek 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 00000000000..ff71f0964a1 --- /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 c5ab4ca75ed..24a6dd02373 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 -- 2.30.2