diff options
Diffstat (limited to 'contrib/gcc/fold-const.c')
-rw-r--r-- | contrib/gcc/fold-const.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/contrib/gcc/fold-const.c b/contrib/gcc/fold-const.c index cbd004e..f260ab4 100644 --- a/contrib/gcc/fold-const.c +++ b/contrib/gcc/fold-const.c @@ -3259,8 +3259,17 @@ make_range (exp, pin_p, plow, phigh) low = range_binop (PLUS_EXPR, type, n_high, 0, integer_one_node, 0); high = range_binop (MINUS_EXPR, type, n_low, 0, - integer_one_node, 0); - in_p = ! in_p; + integer_one_node, 0); + + /* If the range is of the form +/- [ x+1, x ], we won't + be able to normalize it. But then, it represents the + whole range or the empty set, so make it +/- [ -, - ]. + */ + if (tree_int_cst_equal (n_low, low) + && tree_int_cst_equal (n_high, high)) + low = high = 0; + else + in_p = ! in_p; } else low = n_low, high = n_high; @@ -5625,7 +5634,15 @@ fold (expr) tree newconst = fold (build (PLUS_EXPR, TREE_TYPE (varop), constop, TREE_OPERAND (varop, 1))); - TREE_SET_CODE (varop, PREINCREMENT_EXPR); + + /* Do not overwrite the current varop to be a preincrement, + create a new node so that we won't confuse our caller who + might create trees and throw them away, reusing the + arguments that they passed to build. This shows up in + the THEN or ELSE parts of ?: being postincrements. */ + varop = build (PREINCREMENT_EXPR, TREE_TYPE (varop), + TREE_OPERAND (varop, 0), + TREE_OPERAND (varop, 1)); /* If VAROP is a reference to a bitfield, we must mask the constant by the width of the field. */ @@ -5669,9 +5686,9 @@ fold (expr) } - t = build (code, type, TREE_OPERAND (t, 0), - TREE_OPERAND (t, 1)); - TREE_OPERAND (t, constopnum) = newconst; + t = build (code, type, + (constopnum == 0) ? newconst : varop, + (constopnum == 1) ? newconst : varop); return t; } } @@ -5684,7 +5701,15 @@ fold (expr) tree newconst = fold (build (MINUS_EXPR, TREE_TYPE (varop), constop, TREE_OPERAND (varop, 1))); - TREE_SET_CODE (varop, PREDECREMENT_EXPR); + + /* Do not overwrite the current varop to be a predecrement, + create a new node so that we won't confuse our caller who + might create trees and throw them away, reusing the + arguments that they passed to build. This shows up in + the THEN or ELSE parts of ?: being postdecrements. */ + varop = build (PREDECREMENT_EXPR, TREE_TYPE (varop), + TREE_OPERAND (varop, 0), + TREE_OPERAND (varop, 1)); if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF && DECL_BIT_FIELD(TREE_OPERAND @@ -5723,9 +5748,9 @@ fold (expr) } - t = build (code, type, TREE_OPERAND (t, 0), - TREE_OPERAND (t, 1)); - TREE_OPERAND (t, constopnum) = newconst; + t = build (code, type, + (constopnum == 0) ? newconst : varop, + (constopnum == 1) ? newconst : varop); return t; } } |