On Thu, Nov 26, 2015 at 05:10:26PM +0100, Marek Polacek wrote:
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2015-11-26 Marek Polacek <[email protected]>
>
> PR c/68513
> * c-gimplify.c (strip_c_maybe_const_expr_r): New.
> (c_gimplify_expr): Call it.
>
> * gcc.dg/torture/pr68513.c: New test.
>
> diff --git gcc/c-family/c-gimplify.c gcc/c-family/c-gimplify.c
> index fc4a44a..c096575 100644
> --- gcc/c-family/c-gimplify.c
> +++ gcc/c-family/c-gimplify.c
> @@ -212,6 +212,21 @@ c_build_bind_expr (location_t loc, tree block, tree body)
>
> /* Gimplification of expression trees. */
>
> +/* Callback for c_gimplify_expr. Strip C_MAYBE_CONST_EXPRs in TP so that
> + they don't leak into the middle end. */
> +
> +static tree
> +strip_c_maybe_const_expr_r (tree *tp, int *walk_subtrees, void *)
> +{
> + if (TREE_CODE (*tp) == C_MAYBE_CONST_EXPR)
> + {
> + gcc_assert (C_MAYBE_CONST_EXPR_PRE (*tp) == NULL_TREE);
> + *tp = C_MAYBE_CONST_EXPR_EXPR (*tp);
> + *walk_subtrees = 0;
> + }
> + return NULL_TREE;
> +}
> +
> /* Do C-specific gimplification on *EXPR_P. PRE_P and POST_P are as in
> gimplify_expr. */
>
> @@ -296,6 +311,10 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p
> ATTRIBUTE_UNUSED,
> return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
> }
>
> + case SAVE_EXPR:
> + walk_tree_without_duplicates (expr_p, strip_c_maybe_const_expr_r,
> NULL);
Shouldn't this be done only if (!SAVE_EXPR_RESOLVED_P (*expr_p))?
Otherwise I fear bad compile time complexity, consider huge tree containing
lots of nested SAVE_EXPRs and every SAVE_EXPR appearing twice or more times
somewhere in the tree. Perhaps the walk should also *walk_subtrees = 0;
for SAVE_EXPRs and start walking &TREE_OPERAND (*expr_p, 0) instead of
expr_p. The nested SAVE_EXPRs would be handled when those are gimplified.
Jakub