re PR fortran/12632 ([g77 only] -fbounds-check ICE)
authorRoger Sayle <roger@eyesopen.com>
Mon, 29 Dec 2003 16:16:39 +0000 (16:16 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Mon, 29 Dec 2003 16:16:39 +0000 (16:16 +0000)
PR fortran/12632
* fold-const.c (fold) <COND_EXPR>: Don't fold a constant condition,
if the type of the selected branch doesn't match its' parent.

* 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: r75203

gcc/ChangeLog
gcc/f/ChangeLog
gcc/f/com.c
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g77.dg/12632.f [new file with mode: 0644]

index 45598358d30aa95f70aaf4f45d370fcec871ec42..486b98145a8c28e89d800e3761ccaebcf2b2b6cf 100644 (file)
@@ -1,3 +1,9 @@
+2003-12-29  Roger Sayle  <roger@eyesopen.com>
+
+       PR fortran/12632
+       * fold-const.c (fold) <COND_EXPR>: Don't fold a constant condition,
+       if the type of the selected branch doesn't match its' parent.
+
 2003-12-29  Jan Hubicka  <jh@suse.cz>
 
        * coverage.c (read_counts_file): Better error messages; cause corrupted
index 99a666f9d355270ed5ce9f97dcfcd11ba5ecf7ae..3dcc5628f70b537b855bd3e04967361335134cf4 100644 (file)
@@ -1,3 +1,14 @@
+2003-12-29  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-06  Kelley Cook  <kcook@gcc.gnu.org>
 
        * Make-lang.in (G77_CROSS_NAME): Delete.
index 535ddbb87e865892885b6346cb4e1efab839341d..a64ef86b17240a57b9e498957a6f9dde7518c3b8 100644 (file)
@@ -638,15 +638,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));
@@ -713,6 +714,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;
@@ -807,13 +812,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.
@@ -899,7 +901,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;
 
@@ -945,7 +947,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;
 
@@ -2037,7 +2039,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);
 
@@ -2055,7 +2057,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);
 
@@ -2088,7 +2090,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 3da0ebf6f46a82110a074da04266e969460d5913..556593243ac335609593fb8f0f95b95cd45e4d94 100644 (file)
@@ -7864,9 +7864,16 @@ fold (tree 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 (TREE_TYPE (tem) == 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 we have A op B ? A : C, we may be able to convert this to a
index 2cccfddf358291955fd4bc604bea62d52166eec6..9f575579a120bc9a9d1e885dc857bcde74613800 100644 (file)
@@ -1,3 +1,8 @@
+2003-12-29  Roger Sayle  <roger@eyesopen.com>
+
+       PR fortran/12632
+       * g77.dg/12632.f: New test case.
+
 2003-12-29  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
        PR c++/13289
diff --git a/gcc/testsuite/g77.dg/12632.f b/gcc/testsuite/g77.dg/12632.f
new file mode 100644 (file)
index 0000000..6801229
--- /dev/null
@@ -0,0 +1,6 @@
+C { dg-do compile }
+C { dg-options "-fbounds-check" }
+       INTEGER I(1)
+       I(2) = 0  ! { dg-error "out of defined range" "out of defined range" }
+       END
+