------- Comment #8 from jakub at gcc dot gnu dot org 2008-01-10 00:00 ------- Patch which cures this: --- gcc/tree-inline.c.jj 2008-01-04 00:53:03.000000000 +0100 +++ gcc/tree-inline.c 2008-01-10 00:48:07.000000000 +0100 @@ -700,7 +700,30 @@ copy_body_r (tree *tp, int *walk_subtree if (! *tp) { if (TREE_CODE (new) == ADDR_EXPR) - *tp = TREE_OPERAND (new, 0); + { + tree t = TREE_OPERAND (new, 0); + if (types_compatible_p (type, TREE_TYPE (t))) + *tp = t; + else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE + && types_compatible_p (TREE_TYPE (TREE_TYPE (t)), + type)) + { + tree type_domain = TYPE_DOMAIN (TREE_TYPE (t)); + tree min_val = size_zero_node; + if (type_domain && TYPE_MIN_VALUE (type_domain)) + min_val = TYPE_MIN_VALUE (type_domain); + *tp = build4 (ARRAY_REF, type, t, min_val, + NULL_TREE, NULL_TREE); + } + else + { + t = build_fold_addr_expr (t); + t = fold_convert (TREE_TYPE (new), t); + *tp = build1 (INDIRECT_REF, type, t); + TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); + id->regimplify = true; + } + } else { *tp = build1 (INDIRECT_REF, type, new); @@ -1210,13 +1233,15 @@ copy_phis_for_bb (basic_block bb, copy_b tree arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge); tree new_arg = arg;
+ id->regimplify = false; walk_tree (&new_arg, copy_body_r, id, NULL); gcc_assert (new_arg); /* With return slot optimization we can end up with non-gimple (foo *)&this->m, fix that here. */ - if (TREE_CODE (new_arg) != SSA_NAME - && TREE_CODE (new_arg) != FUNCTION_DECL - && !is_gimple_val (new_arg)) + if ((TREE_CODE (new_arg) != SSA_NAME + && TREE_CODE (new_arg) != FUNCTION_DECL + && !is_gimple_val (new_arg)) + || id->regimplify) { tree stmts = NULL_TREE; new_arg = force_gimple_operand (new_arg, &stmts, --- gcc/tree-ssa-operands.c.jj 2008-01-04 00:53:03.000000000 +0100 +++ gcc/tree-ssa-operands.c 2008-01-10 00:38:25.000000000 +0100 @@ -1663,7 +1663,7 @@ get_addr_dereference_operands (tree stmt /* If we don't know what this pointer points to then we have to make sure to not prune virtual operands based on offset and size. */ - if (v_ann->symbol_mem_tag) + if (v_ann && v_ann->symbol_mem_tag) { add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags, full_ref, 0, -1, false); --- gcc/testsuite/gcc.dg/pr34668-1.c.jj 2008-01-10 00:55:59.000000000 +0100 +++ gcc/testsuite/gcc.dg/pr34668-1.c 2008-01-10 00:59:02.000000000 +0100 @@ -0,0 +1,19 @@ +/* PR c/34668 */ +/* { dg-do compile } */ +/* { dg-options "--combine -O2" } */ +/* { dg-additional-sources "pr34668-2.c" } */ + +struct optab { unsigned code; }; +extern struct optab optab_table[1]; + +void +init_optab (struct optab *op) +{ + op->code = 0xdead; +} + +void +set_conv_libfunc (void) +{ + init_optab (&optab_table[0]); +} --- gcc/testsuite/gcc.dg/pr34668-2.c.jj 2008-01-10 00:56:02.000000000 +0100 +++ gcc/testsuite/gcc.dg/pr34668-2.c 2008-01-10 00:56:36.000000000 +0100 @@ -0,0 +1,5 @@ +/* PR c/34668 */ +/* { dg-do compile } */ + +struct optab { unsigned code; }; +extern struct optab optab_table[1]; -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34668