From patchwork Sat Jul 3 13:11:12 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Fix ICE on conditional expression in Ada Date: Sat, 03 Jul 2010 03:11:12 -0000 From: Eric Botcazou X-Patchwork-Id: 57806 Message-Id: <201007031511.13007.ebotcazou@adacore.com> To: gcc-patches@gcc.gnu.org This new Ada 2012 feature is going to stretch the middle-end support for statement expressions because the front-end can insert arbitrarily complex statements within the arms of conditional expressions. The attached testcase triggers an ICE in the tree unsharing phase because we have a BIND_EXPR under a SAVE_EXPR and we unshare subtrees of SAVE_EXPRs in Ada (deep unsharing). Fixed by handling BIND_EXPR like SAVE_EXPR/TARGET_EXPR i.e stopping the unsharing instead of aborting, except with deep unsharing. This doesn't change anything except for Ada. Tested on i586-suse-linux and applied on the mainline as obvious. 2010-07-03 Eric Botcazou * gimplify.c (mostly_copy_tree_r): Deal with BIND_EXPR. 2010-07-03 Eric Botcazou * gnat.dg/cond_expr1.adb: New test. Index: gimplify.c =================================================================== --- gimplify.c (revision 161767) +++ gimplify.c (working copy) @@ -868,9 +868,9 @@ mostly_copy_tree_r (tree *tp, int *walk_ tree t = *tp; enum tree_code code = TREE_CODE (t); - /* Do not copy SAVE_EXPR or TARGET_EXPR nodes themselves, but copy - their subtrees if we can make sure to do it only once. */ - if (code == SAVE_EXPR || code == TARGET_EXPR) + /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but + copy their subtrees if we can make sure to do it only once. */ + if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR) { if (data && !pointer_set_insert ((struct pointer_set_t *)data, t)) ; @@ -895,10 +895,7 @@ mostly_copy_tree_r (tree *tp, int *walk_ /* Leave the bulk of the work to copy_tree_r itself. */ else - { - gcc_assert (code != BIND_EXPR); - copy_tree_r (tp, walk_subtrees, NULL); - } + copy_tree_r (tp, walk_subtrees, NULL); return NULL_TREE; }