From 9866586167b7591ff1bbfe59ccdeba1dad796246 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 19 Nov 2008 17:38:15 +0000 Subject: [PATCH] tree.c (build2_stat): Allow non-POINTER_PLUS_EXPRs with non-sizetype offsets if... 2008-11-19 Richard Guenther * 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. From-SVN: r142009 --- gcc/ChangeLog | 8 ++++++++ gcc/expr.c | 8 ++++++++ gcc/tree.c | 9 +++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d3884d1bd80..6b972eec096 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2008-11-19 Richard Guenther + + * 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 * config.gcc: Unobsolete mips-sgi-irix[56]*. diff --git a/gcc/expr.c b/gcc/expr.c index 31af3aa9c49..0f46b199883 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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. */ diff --git a/gcc/tree.c b/gcc/tree.c index 184d2471744..e74b7792127 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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))