Commit d74641bd by Richard Sandiford Committed by Richard Sandiford

Add a DECL_EXPR for VLA pointer casts (PR 84305)

This PR was about a case in which we ended up with a MULT_EXPR
that was shared between an ungimplified VLA type and a pointer
calculation.  The SSA names used in the pointer calculation were
later freed, but they were still there in the VLA, and caused an
ICE when remapping the types during inlinling.

The fix is to add a DECL_EXPR that forces the VLA type sizes to be
gimplified too, but the tricky part is deciding where.  As the comment
in grokdeclarator says, we can't just add it to the statement list,
since the size might only be conditionally evaluated.  It might also
end up being evaluated out of sequence.

The patch gets around that by putting the DECL_EXPR in a BIND_EXPR
and adding the BIND_EXPR to the list of things that need to be
evaluated for the declarator.

2018-02-13  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/c/
	PR c/84305
	* c-decl.c (grokdeclarator): Create an anonymous TYPE_DECL
	in PARM and TYPENAME contexts too, but attach it to a BIND_EXPR
	and include the BIND_EXPR in the list of things that need to be
	pre-evaluated.

gcc/testsuite/
	PR c/84305
	* gcc.c-torture/compile/pr84305.c: New test.

From-SVN: r257620
parent 5cd1af49
2018-02-13 Richard Sandiford <richard.sandiford@linaro.org>
PR c/84305
* c-decl.c (grokdeclarator): Create an anonymous TYPE_DECL
in PARM and TYPENAME contexts too, but attach it to a BIND_EXPR
and include the BIND_EXPR in the list of things that need to be
pre-evaluated.
2018-02-09 Nathan Sidwell <nathan@acm.org> 2018-02-09 Nathan Sidwell <nathan@acm.org>
PR c/84293 PR c/84293
......
...@@ -6479,28 +6479,53 @@ grokdeclarator (const struct c_declarator *declarator, ...@@ -6479,28 +6479,53 @@ grokdeclarator (const struct c_declarator *declarator,
type has a name/declaration of it's own, but special attention type has a name/declaration of it's own, but special attention
is required if the type is anonymous. is required if the type is anonymous.
We handle the NORMAL and FIELD contexts here by attaching an We attach an artificial TYPE_DECL to such pointed-to type
artificial TYPE_DECL to such pointed-to type. This forces the and arrange for it to be included in a DECL_EXPR. This
sizes evaluation at a safe point and ensures it is not deferred forces the sizes evaluation at a safe point and ensures it
until e.g. within a deeper conditional context. is not deferred until e.g. within a deeper conditional context.
We expect nothing to be needed here for PARM or TYPENAME. PARM contexts have no enclosing statement list that
Pushing a TYPE_DECL at this point for TYPENAME would actually can hold the DECL_EXPR, so we need to use a BIND_EXPR
be incorrect, as we might be in the middle of an expression instead, and add it to the list of expressions that
with side effects on the pointed-to type size "arguments" prior need to be evaluated.
to the pointer declaration point and the fake TYPE_DECL in the
enclosing context would force the size evaluation prior to the TYPENAME contexts do have an enclosing statement list,
side effects. */ but it would be incorrect to use it, as the size should
only be evaluated if the containing expression is
evaluated. We might also be in the middle of an
expression with side effects on the pointed-to type size
"arguments" prior to the pointer declaration point and
the fake TYPE_DECL in the enclosing context would force
the size evaluation prior to the side effects. We therefore
use BIND_EXPRs in TYPENAME contexts too. */
if (!TYPE_NAME (type) if (!TYPE_NAME (type)
&& (decl_context == NORMAL || decl_context == FIELD)
&& variably_modified_type_p (type, NULL_TREE)) && variably_modified_type_p (type, NULL_TREE))
{ {
tree bind = NULL_TREE;
if (decl_context == TYPENAME || decl_context == PARM)
{
bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
NULL_TREE, NULL_TREE);
TREE_SIDE_EFFECTS (bind) = 1;
BIND_EXPR_BODY (bind) = push_stmt_list ();
push_scope ();
}
tree decl = build_decl (loc, TYPE_DECL, NULL_TREE, type); tree decl = build_decl (loc, TYPE_DECL, NULL_TREE, type);
DECL_ARTIFICIAL (decl) = 1; DECL_ARTIFICIAL (decl) = 1;
pushdecl (decl); pushdecl (decl);
finish_decl (decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); finish_decl (decl, loc, NULL_TREE, NULL_TREE, NULL_TREE);
TYPE_NAME (type) = decl; TYPE_NAME (type) = decl;
if (bind)
{
pop_scope ();
BIND_EXPR_BODY (bind)
= pop_stmt_list (BIND_EXPR_BODY (bind));
if (*expr)
*expr = build2 (COMPOUND_EXPR, void_type_node, *expr,
bind);
else
*expr = bind;
}
} }
type = c_build_pointer_type (type); type = c_build_pointer_type (type);
......
2018-02-13 Richard Sandiford <richard.sandiford@linaro.org>
PR c/84305
* gcc.c-torture/compile/pr84305.c: New test.
2018-02-13 Jakub Jelinek <jakub@redhat.com> 2018-02-13 Jakub Jelinek <jakub@redhat.com>
PR target/84335 PR target/84335
......
int res, a, b;
void *foo;
static void f2 (int arg) { res = ((int (*)[arg][b]) foo)[0][0][0]; }
void f1 (void) { f2 (a); }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment