diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/expr.c | 8 | ||||
-rw-r--r-- | gcc/tree.c | 9 |
3 files changed, 23 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d3884d1..6b972ee 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2008-11-19 Richard Guenther <rguenther@suse.de> + + * tree.c (build2_stat): Allow non-POINTER_PLUS_EXPRs with + non-sizetype offsets if their precision matches that of + the pointer. + * expr.c (expand_expr_real_1): Always sign-extend the offset + operand of a POINTER_PLUS_EXPR. + 2008-11-19 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> * config.gcc: Unobsolete mips-sgi-irix[56]*. @@ -8334,6 +8334,14 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, /* Even though the sizetype mode and the pointer's mode can be different expand is able to handle this correctly and get the correct result out of the PLUS_EXPR code. */ + /* Make sure to sign-extend the sizetype offset in a POINTER_PLUS_EXPR + if sizetype precision is smaller than pointer precision. */ + if (TYPE_PRECISION (sizetype) < TYPE_PRECISION (type)) + exp = build2 (PLUS_EXPR, type, + TREE_OPERAND (exp, 0), + fold_convert (type, + fold_convert (ssizetype, + TREE_OPERAND (exp, 1)))); case PLUS_EXPR: /* Check if this is a case for multiplication and addition. */ @@ -3289,8 +3289,13 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL) gcc_assert (TREE_CODE_LENGTH (code) == 2); if ((code == MINUS_EXPR || code == PLUS_EXPR || code == MULT_EXPR) - && arg0 && arg1 && tt && POINTER_TYPE_P (tt)) - gcc_assert (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST); + && arg0 && arg1 && tt && POINTER_TYPE_P (tt) + /* When sizetype precision doesn't match that of pointers + we need to be able to build explicit extensions or truncations + of the offset argument. */ + && TYPE_PRECISION (sizetype) == TYPE_PRECISION (tt)) + gcc_assert (TREE_CODE (arg0) == INTEGER_CST + && TREE_CODE (arg1) == INTEGER_CST); if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt) gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0)) |