]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/12632 ([g77 only] -fbounds-check ICE)
authorRoger Sayle <roger@eyesopen.com>
Thu, 1 Jan 2004 04:44:59 +0000 (04:44 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Thu, 1 Jan 2004 04:44:59 +0000 (04:44 +0000)
PR fortran/12632
* tree.c (integer_nonzerop): New predicate for nonzero integers.
* tree.h (integer_nonzerop): Add function prototype.
* fold-const.c (fold) <COND_EXPR>: Don't fold a constant condition,
if we'd replace a COND_EXPR of non-void type by one of its operands
of void type.

* com.c (ffecom_subscript_check_): Take as an extra argument the
(possibly NULL) decl of the array.  Don't create unnecessary tree
nodes if the array index is known to be safe at compile-time.
If the array index is unsafe, force the array decl into memory to
avoid RTL expansion problems.
(ffecom_array_ref_): Update calls to ffecom_subscript_check_.
(ffecom_char_args_x_): Likewise.

* g77.dg/12632.f: New test case.

From-SVN: r75295

gcc/ChangeLog
gcc/f/ChangeLog
gcc/f/com.c
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/tree.c
gcc/tree.h

index 10c31ad4ffe8fef581f50b78cd8596669c87b911..e569f4d122c837787d571bc3f260cf5fabc76a54 100644 (file)
@@ -1,3 +1,12 @@
+2003-12-31  Roger Sayle  <roger@eyesopen.com>
+
+       PR fortran/12632
+       * tree.c (integer_nonzerop): New predicate for nonzero integers.
+       * tree.h (integer_nonzerop): Add function prototype.
+       * fold-const.c (fold) <COND_EXPR>: Don't fold a constant condition,
+       if we'd replace a COND_EXPR of non-void type by one of its operands
+       of void type.
+
 2003-12-31  Kazu Hirata  <kazu@cs.umass.edu>
 
        Backport from mainline:
index cd6f75df136fa4515d2831dab118104bfe6ae1a5..2049f2aad3556abd4d78439cca0003e1fe8fe329 100644 (file)
@@ -1,3 +1,14 @@
+2003-12-31  Roger Sayle  <roger@eyesopen.com>
+
+       PR fortran/12632
+       * com.c (ffecom_subscript_check_): Take as an extra argument the
+       (possibly NULL) decl of the array.  Don't create unnecessary tree
+       nodes if the array index is known to be safe at compile-time.
+       If the array index is unsafe, force the array decl into memory to
+       avoid RTL expansion problems.
+       (ffecom_array_ref_): Update calls to ffecom_subscript_check_.
+       (ffecom_char_args_x_): Likewise.
+
 2003-12-05  Toon Moene  <toon@moene.indiv.nluug.nl>
 
        PR fortran/12633
index fca0f94ac9d6f7d7e76e060492fe91d62b2bd164..14445cdd13ebf5a13143149da3d67ce8c41ead75 100644 (file)
@@ -639,15 +639,16 @@ static GTY(()) tree shadowed_labels;
 \f
 /* Return the subscript expression, modified to do range-checking.
 
-   `array' is the array to be checked against.
+   `array' is the array type to be checked against.
    `element' is the subscript expression to check.
    `dim' is the dimension number (starting at 0).
    `total_dims' is the total number of dimensions (0 for CHARACTER substring).
+   `item' is the array decl or NULL_TREE.
 */
 
 static tree
 ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
-                        const char *array_name)
+                        const char *array_name, tree item)
 {
   tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
   tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
@@ -714,6 +715,10 @@ ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
         }
     }
 
+  /* If the array index is safe at compile-time, return element.  */
+  if (integer_nonzerop (cond))
+    return element;
+
   {
     int len;
     char *proc;
@@ -808,13 +813,10 @@ ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
   TREE_SIDE_EFFECTS (die) = 1;
   die = convert (void_type_node, die);
 
-  element = ffecom_3 (COND_EXPR,
-                     TREE_TYPE (element),
-                     cond,
-                     element,
-                     die);
+  if (integer_zerop (cond) && item)
+    ffe_mark_addressable (item);
 
-  return element;
+  return ffecom_3 (COND_EXPR, TREE_TYPE (element), cond, element, die);
 }
 
 /* Return the computed element of an array reference.
@@ -900,7 +902,7 @@ ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
          element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
          if (flag_bounds_check)
            element = ffecom_subscript_check_ (array, element, i, total_dims,
-                                              array_name);
+                                              array_name, item);
          if (element == error_mark_node)
            return element;
 
@@ -946,7 +948,7 @@ ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
          element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
          if (flag_bounds_check)
            element = ffecom_subscript_check_ (array, element, i, total_dims,
-                                              array_name);
+                                              array_name, item);
          if (element == error_mark_node)
            return element;
 
@@ -2045,7 +2047,7 @@ ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
                end_tree = ffecom_expr (end);
                if (flag_bounds_check)
                  end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
-                                                     char_name);
+                                                     char_name, NULL_TREE);
                end_tree = convert (ffecom_f2c_ftnlen_type_node,
                                    end_tree);
 
@@ -2063,7 +2065,7 @@ ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
            start_tree = ffecom_expr (start);
            if (flag_bounds_check)
              start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
-                                                   char_name);
+                                                   char_name, NULL_TREE);
            start_tree = convert (ffecom_f2c_ftnlen_type_node,
                                  start_tree);
 
@@ -2096,7 +2098,7 @@ ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
                end_tree = ffecom_expr (end);
                if (flag_bounds_check)
                  end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
-                                                     char_name);
+                                                     char_name, NULL_TREE);
                end_tree = convert (ffecom_f2c_ftnlen_type_node,
                                    end_tree);
 
index 94682d477ee434dbcb535eaf764549d2c530e667..bf3c1fa93be1c4b055f76618b9c394d5745205d3 100644 (file)
@@ -6785,9 +6785,17 @@ fold (expr)
       /* Pedantic ANSI C says that a conditional expression is never an lvalue,
         so all simple results must be passed through pedantic_non_lvalue.  */
       if (TREE_CODE (arg0) == INTEGER_CST)
-       return pedantic_non_lvalue
-         (TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1)));
-      else if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0))
+       {
+         tem = TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1));
+         /* Only optimize constant conditions when the selected branch
+            has the same type as the COND_EXPR.  This avoids optimizing
+            away "c ? x : throw", where the throw has a void type.  */
+         if (! VOID_TYPE_P (TREE_TYPE (tem))
+             || VOID_TYPE_P (TREE_TYPE (t)))
+           return pedantic_non_lvalue (tem);
+         return t;
+       }
+      if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0))
        return pedantic_omit_one_operand (type, arg1, arg0);
 
       /* If the second operand is zero, invert the comparison and swap
index 52217a05f72c61250db69aa2dba852f5dabbb064..3b58c492f1d9a15be241a7b21980971bbb7d14ad 100644 (file)
@@ -1,3 +1,8 @@
+2003-12-31  Roger Sayle  <roger@eyesopen.com>
+
+       PR fortran/12632
+       * g77.dg/12632.f: New test case.
+
 2003-12-29  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/13445
index e8c2541c1d99a5e242b8d1ff14e3e72966183715..0ecde79d4e0a71b0a9511d861b3281aa51efcf61 100644 (file)
@@ -723,6 +723,23 @@ integer_pow2p (expr)
          || (low == 0 && (high & (high - 1)) == 0));
 }
 
+/* Return 1 if EXPR is an integer constant other than zero or a
+   complex constant other than zero.  */
+
+int
+integer_nonzerop (tree expr)
+{
+  STRIP_NOPS (expr);
+
+  return ((TREE_CODE (expr) == INTEGER_CST
+          && ! TREE_CONSTANT_OVERFLOW (expr)
+          && (TREE_INT_CST_LOW (expr) != 0
+              || TREE_INT_CST_HIGH (expr) != 0))
+         || (TREE_CODE (expr) == COMPLEX_CST
+             && (integer_nonzerop (TREE_REALPART (expr))
+                 || integer_nonzerop (TREE_IMAGPART (expr)))));
+}
+
 /* Return the power of two represented by a tree node known to be a
    power of two.  */
 
index 1ad4b142c78aff924c7c193567813e5503174162..275511f838812b1b5026dd4961930f0d2a55c9c4 100644 (file)
@@ -2637,6 +2637,11 @@ extern int integer_all_onesp             PARAMS ((tree));
 
 extern int integer_pow2p               PARAMS ((tree));
 
+/* integer_nonzerop (tree x) is nonzero if X is an integer constant
+   with a nonzero value.  */
+
+extern int integer_nonzerop (tree);
+
 /* staticp (tree x) is nonzero if X is a reference to data allocated
    at a fixed address in memory.  */