diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-11-19 17:38:15 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-11-19 17:38:15 +0000 |
commit | 5c485e88d60cd5ef69d53b4c82b185a3a09a91b2 (patch) | |
tree | ff9eb564008c7a7510b130d8f124d17e3259003c | |
parent | 93aa09170cc6442c0cb70f1c8d09b9e2ca31b194 (diff) | |
download | gcc-5c485e88d60cd5ef69d53b4c82b185a3a09a91b2.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142009 138bc75d-0d04-0410-961f-82ee72b054a4
-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 d3884d1bd80..6b972eec096 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]*. 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)) |