aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/expr.c8
-rw-r--r--gcc/tree.c9
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]*.
diff --git a/gcc/expr.c b/gcc/expr.c
index 31af3aa..0f46b19 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 184d247..e74b779 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))