aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-04-23 21:11:36 +0200
committerJakub Jelinek <jakub@redhat.com>2020-04-23 21:11:36 +0200
commitbca558de2a24b2a78c6a321d6cec384e07759d77 (patch)
tree001650ca80858285d7089a14cb14d6787412a3fd /gcc/tree.c
parent06eca1acafa27e19e82dc73927394a7a4d0bdbc5 (diff)
downloadgcc-bca558de2a24b2a78c6a321d6cec384e07759d77.zip
gcc-bca558de2a24b2a78c6a321d6cec384e07759d77.tar.gz
gcc-bca558de2a24b2a78c6a321d6cec384e07759d77.tar.bz2
tree: Fix up get_narrower [PR94724]
In the recent get_narrower change, I wanted it to be efficient and avoid recursion if there are many nested COMPOUND_EXPRs. That builds the COMPOUND_EXPR nest with the right arguments, but as build2_loc computes some flags like TREE_SIDE_EFFECTS, TREE_CONSTANT and TREE_READONLY, when it is called with something that will not be the argument in the end, those flags are computed incorrectly. So, this patch instead uses an auto_vec and builds them in the reverse order so when they are built, they are built with the correct operands. 2020-04-23 Jakub Jelinek <jakub@redhat.com> PR middle-end/94724 * tree.c (get_narrower): Instead of creating COMPOUND_EXPRs temporarily with non-final second operand and updating it later, push COMPOUND_EXPRs into a vector and process it in reverse, creating COMPOUND_EXPRs with the final operands. * gcc.c-torture/execute/pr94724.c: New test.
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index fa956da..da6b8e2 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -8881,18 +8881,22 @@ get_narrower (tree op, int *unsignedp_ptr)
if (TREE_CODE (op) == COMPOUND_EXPR)
{
- while (TREE_CODE (op) == COMPOUND_EXPR)
+ do
op = TREE_OPERAND (op, 1);
+ while (TREE_CODE (op) == COMPOUND_EXPR);
tree ret = get_narrower (op, unsignedp_ptr);
if (ret == op)
return win;
- op = win;
- for (tree *p = &win; TREE_CODE (op) == COMPOUND_EXPR;
- op = TREE_OPERAND (op, 1), p = &TREE_OPERAND (*p, 1))
- *p = build2_loc (EXPR_LOCATION (op), COMPOUND_EXPR,
- TREE_TYPE (ret), TREE_OPERAND (op, 0),
- ret);
- return win;
+ auto_vec <tree, 16> v;
+ unsigned int i;
+ for (tree op = win; TREE_CODE (op) == COMPOUND_EXPR;
+ op = TREE_OPERAND (op, 1))
+ v.safe_push (op);
+ FOR_EACH_VEC_ELT_REVERSE (v, i, op)
+ ret = build2_loc (EXPR_LOCATION (op), COMPOUND_EXPR,
+ TREE_TYPE (win), TREE_OPERAND (op, 0),
+ ret);
+ return ret;
}
while (TREE_CODE (op) == NOP_EXPR)
{