tree.c (build2_stat): Allow non-POINTER_PLUS_EXPRs with non-sizetype offsets if...
authorRichard Guenther <rguenther@suse.de>
Wed, 19 Nov 2008 17:38:15 +0000 (17:38 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 19 Nov 2008 17:38:15 +0000 (17:38 +0000)
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.

From-SVN: r142009

gcc/ChangeLog
gcc/expr.c
gcc/tree.c

index d3884d1bd80b7a13a3efa3e8e0c13ee12f3a0516..6b972eec096fb84434b951f28913530c85a73b56 100644 (file)
@@ -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]*.
index 31af3aa9c4920c2ed5b4764f69f927e9d493102c..0f46b199883b4525b3b3d77f0d0fc596dcf45c17 100644 (file)
@@ -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.  */
index 184d247174441a465a88c8dbcdf5812c0da2ee06..e74b779212733fa692a8c97dafc0017b9c51486d 100644 (file)
@@ -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))