This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [tree-ssa]: Invalid GIMPLE generated by C++ front end
- From: Jason Merrill <jason at redhat dot com>
- To: Daniel Berlin <dberlin at dberlin dot org>
- Cc: Diego Novillo <dnovillo at redhat dot com>, gcc at gcc dot gnu dot org, Jason Merrill <jason at redhat dot com>
- Date: Wed, 13 Aug 2003 16:52:24 -0400
- Subject: Re: [tree-ssa]: Invalid GIMPLE generated by C++ front end
- References: <D69115FE-CDC7-11D7-8304-000A95A34564@dberlin.org>
On Wed, 13 Aug 2003 15:53:41 -0400, Daniel Berlin <dberlin@dberlin.org> wrote:
> I've been seeing expressions like T.2 = (char * const &)&<UVbbd0>
> generated by the C++ FE lately (compiling string-inst.cc on darwin, for
> instance).
>
> Are these actually valid GIMPLE?
No. I ran into a similar crash recently; the problem turned out to be with
the inliner inserting nops during &* elimination. I've attached a patch
below. Does it fix your bug?
> Going by the grammar, they aren't, and they are causing PTA to miss some
> variables because they fail is_gimple_modify_expr.
Incidentally, I'm in the process of converting all of the gimplification
predicates to only check the tree code in most cases, since that's all I
care about during gimplification. The underlying nodes will already have
been massaged into the right form by recursive gimplification.
But your comment brings up the possibility that other passes will want to
be able to check whether or not a transformation leaves the code in gimple
form. Is this what you need? If so, would calling back into gimplify_expr
be a reasonable alternative (if it worked)?
*** tree-inline.c.~1~ 2003-08-12 13:41:34.000000000 -0400
--- tree-inline.c 2003-08-12 15:39:46.000000000 -0400
*************** copy_body_r (tree *tp, int *walk_subtree
*** 460,465 ****
--- 464,480 ----
if (TREE_CODE (value) == INDIRECT_REF)
{
*tp = convert (TREE_TYPE (*tp), TREE_OPERAND (value, 0));
+ if (TREE_CODE (*tp) == NOP_EXPR)
+ {
+ if (POINTER_TYPE_P (TREE_TYPE (*tp))
+ && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (*tp, 0)))
+ && (TREE_TYPE (TREE_TYPE (*tp))
+ == TREE_TYPE (TREE_TYPE (TREE_OPERAND (*tp, 0)))))
+ /* Strip a conversion between pointer and reference. */
+ *tp = TREE_OPERAND (*tp, 0);
+ else if (keep_function_tree_in_gimple_form (id->decl))
+ abort ();
+ }
return copy_body_r (tp, walk_subtrees, data);
}
}
*************** copy_body_r (tree *tp, int *walk_subtree
*** 478,485 ****
STRIP_NOPS (value);
if (TREE_CODE (value) == ADDR_EXPR)
{
! *tp = (tree) n->value;
! return copy_body_r (tp, walk_subtrees, data);
}
}
}
--- 493,506 ----
STRIP_NOPS (value);
if (TREE_CODE (value) == ADDR_EXPR)
{
! if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (value, 0)))
! == TYPE_MAIN_VARIANT (TREE_TYPE (*tp)))
! {
! *tp = TREE_OPERAND (value, 0);
! return copy_body_r (tp, walk_subtrees, data);
! }
! else if (keep_function_tree_in_gimple_form (id->decl))
! abort ();
}
}
}