OSDN Git Service

* dependency.c (gfc_is_inside_range): Delete.
[pf3gnuchains/gcc-fork.git] / gcc / fortran / data.c
index 2999af2..fdb9856 100644 (file)
@@ -1,5 +1,5 @@
 /* Supporting functions for resolving DATA statement.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Lifang Zeng <zlf605@hotmail.com>
 
 This file is part of GCC.
@@ -16,8 +16,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330,Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor,Boston, MA
+02110-1301, USA.  */
 
 
 /* Notes for DATA statement implementation:
@@ -26,7 +26,7 @@ Software Foundation, 59 Temple Place - Suite 330,Boston, MA
    during resolveing DATA statement. Refer to check_data_variable and
    traverse_data_list in resolve.c.
                                                                                
-   The complexity exists in the handleing of array section, implied do
+   The complexity exists in the handling of array section, implied do
    and array of struct appeared in DATA statement.
                                                                                
    We call gfc_conv_structure, gfc_con_array_array_initializer,
@@ -35,7 +35,6 @@ Software Foundation, 59 Temple Place - Suite 330,Boston, MA
 
 #include "config.h"
 #include "gfortran.h"
-#include "assert.h"
 
 static void formalize_init_expr (gfc_expr *);
 
@@ -133,7 +132,7 @@ find_con_by_component (gfc_component *com, gfc_constructor *con)
 }
 
 
-/* Create a character type intialization expression from RVALUE.
+/* Create a character type initialization expression from RVALUE.
    TS [and REF] describe [the substring of] the variable being initialized.
    INIT is thh existing initializer, not NULL.  Initialization is performed
    according to normal assignment rules.  */
@@ -168,7 +167,7 @@ create_character_intializer (gfc_expr * init, gfc_typespec * ts,
 
   if (ref)
     {
-      assert (ref->type == REF_SUBSTRING);
+      gcc_assert (ref->type == REF_SUBSTRING);
 
       /* Only set a substring of the destination.  Fortran substring bounds
          are one-based [start, end], we want zero based [start, end).  */
@@ -225,7 +224,7 @@ gfc_assign_data_value (gfc_expr * lvalue, gfc_expr * rvalue, mpz_t index)
       if (ref->type == REF_SUBSTRING)
        {
          /* A substring should always br the last subobject reference.  */
-         assert (ref->next == NULL);
+         gcc_assert (ref->next == NULL);
          break;
        }
 
@@ -250,7 +249,7 @@ gfc_assign_data_value (gfc_expr * lvalue, gfc_expr * rvalue, mpz_t index)
              expr->rank = ref->u.ar.as->rank;
            }
          else
-           assert (expr->expr_type == EXPR_ARRAY);
+           gcc_assert (expr->expr_type == EXPR_ARRAY);
 
          if (ref->u.ar.type == AR_ELEMENT)
            get_array_index (&ref->u.ar, &offset);
@@ -279,7 +278,7 @@ gfc_assign_data_value (gfc_expr * lvalue, gfc_expr * rvalue, mpz_t index)
              expr->ts.derived = ref->u.c.sym;
            }
          else
-           assert (expr->expr_type == EXPR_STRUCTURE);
+           gcc_assert (expr->expr_type == EXPR_STRUCTURE);
          last_ts = &ref->u.c.component->ts;
 
          /* Find the same element in the existing constructor.  */
@@ -297,7 +296,7 @@ gfc_assign_data_value (gfc_expr * lvalue, gfc_expr * rvalue, mpz_t index)
          break;
 
        default:
-         abort ();
+         gcc_unreachable ();
        }
 
       if (init == NULL)
@@ -316,8 +315,19 @@ gfc_assign_data_value (gfc_expr * lvalue, gfc_expr * rvalue, mpz_t index)
     expr = create_character_intializer (init, last_ts, ref, rvalue);
   else
     {
-      /* We should never be overwriting an existing initializer.  */
-      assert (!init);
+      /* Overwriting an existing initializer is non-standard but usually only
+        provokes a warning from other compilers.  */
+      if (init != NULL)
+       {
+         /* Order in which the expressions arrive here depends on whether they
+            are from data statements or F95 style declarations. Therefore,
+            check which is the most recent.  */
+         expr = (init->where.lb->linenum > rvalue->where.lb->linenum) ?
+                   init : rvalue;
+         gfc_notify_std (GFC_STD_GNU, "Extension: re-initialization "
+                         "of '%s' at %L",  symbol->name, &expr->where);
+         return;
+       }
 
       expr = gfc_copy_expr (rvalue);
       if (!gfc_compare_types (&lvalue->ts, &expr->ts))
@@ -330,7 +340,7 @@ gfc_assign_data_value (gfc_expr * lvalue, gfc_expr * rvalue, mpz_t index)
     last_con->expr = expr;
 }
 
-/* Similarly, but initialize REPEAT consectutive values in LVALUE the same
+/* Similarly, but initialize REPEAT consecutive values in LVALUE the same
    value in RVALUE.  For the nonce, LVALUE must refer to a full array, not
    an array section.  */
 
@@ -375,7 +385,7 @@ gfc_assign_data_value_range (gfc_expr * lvalue, gfc_expr * rvalue,
              expr->rank = ref->u.ar.as->rank;
            }
          else
-           assert (expr->expr_type == EXPR_ARRAY);
+           gcc_assert (expr->expr_type == EXPR_ARRAY);
 
          if (ref->u.ar.type == AR_ELEMENT)
            {
@@ -383,7 +393,7 @@ gfc_assign_data_value_range (gfc_expr * lvalue, gfc_expr * rvalue,
 
              /* This had better not be the bottom of the reference.
                 We can still get to a full array via a component.  */
-             assert (ref->next != NULL);
+             gcc_assert (ref->next != NULL);
            }
          else
            {
@@ -392,8 +402,8 @@ gfc_assign_data_value_range (gfc_expr * lvalue, gfc_expr * rvalue,
              /* We're at a full array or an array section.  This means
                 that we've better have found a full array, and that we're
                 at the bottom of the reference.  */
-             assert (ref->u.ar.type == AR_FULL);
-             assert (ref->next == NULL);
+             gcc_assert (ref->u.ar.type == AR_FULL);
+             gcc_assert (ref->next == NULL);
            }
 
          /* Find the same element in the existing constructor.  */
@@ -410,7 +420,7 @@ gfc_assign_data_value_range (gfc_expr * lvalue, gfc_expr * rvalue,
              gfc_insert_constructor (expr, con);
            }
          else
-           assert (ref->next != NULL);
+           gcc_assert (ref->next != NULL);
          break;
 
        case REF_COMPONENT:
@@ -422,7 +432,7 @@ gfc_assign_data_value_range (gfc_expr * lvalue, gfc_expr * rvalue,
              expr->ts.derived = ref->u.c.sym;
            }
          else
-           assert (expr->expr_type == EXPR_STRUCTURE);
+           gcc_assert (expr->expr_type == EXPR_STRUCTURE);
          last_ts = &ref->u.c.component->ts;
 
          /* Find the same element in the existing constructor.  */
@@ -440,12 +450,12 @@ gfc_assign_data_value_range (gfc_expr * lvalue, gfc_expr * rvalue,
 
          /* Since we're only intending to initialize arrays here,
             there better be an inner reference.  */
-         assert (ref->next != NULL);
+         gcc_assert (ref->next != NULL);
          break;
 
        case REF_SUBSTRING:
        default:
-         abort ();
+         gcc_unreachable ();
        }
 
       if (init == NULL)
@@ -460,12 +470,17 @@ gfc_assign_data_value_range (gfc_expr * lvalue, gfc_expr * rvalue,
       last_con = con;
     }
 
-  /* We should never be overwriting an existing initializer.  */
-  assert (!init);
+  if (last_ts->type == BT_CHARACTER)
+    expr = create_character_intializer (init, last_ts, NULL, rvalue);
+  else
+    {
+      /* We should never be overwriting an existing initializer.  */
+      gcc_assert (!init);
 
-  expr = gfc_copy_expr (rvalue);
-  if (!gfc_compare_types (&lvalue->ts, &expr->ts))
-    gfc_convert_type (expr, &lvalue->ts, 0);
+      expr = gfc_copy_expr (rvalue);
+      if (!gfc_compare_types (&lvalue->ts, &expr->ts))
+       gfc_convert_type (expr, &lvalue->ts, 0);
+    }
 
   if (last_con == NULL)
     symbol->value = expr;
@@ -543,7 +558,7 @@ gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar,
 
 
 /* Rearrange a structure constructor so the elements are in the specified
-   order.  Also insert NULL entries if neccessary.  */
+   order.  Also insert NULL entries if necessary.  */
 
 static void
 formalize_structure_cons (gfc_expr * expr)
@@ -557,7 +572,7 @@ formalize_structure_cons (gfc_expr * expr)
 
   c = expr->value.constructor;
 
-  /* Constructor is already fomalized.  */
+  /* Constructor is already formalized.  */
   if (c->n.component == NULL)
     return;
 
@@ -599,7 +614,7 @@ formalize_structure_cons (gfc_expr * expr)
          tail = tail->next;
        }
     }
-  assert (c == NULL);
+  gcc_assert (c == NULL);
   expr->value.constructor = head;
 }
 
@@ -683,7 +698,7 @@ gfc_get_section_index (gfc_array_ref *ar, mpz_t *section_index, mpz_t *offset)
          gfc_internal_error ("TODO: Vector sections in data statements");
 
        default:
-         abort ();
+         gcc_unreachable ();
        }
 
       mpz_sub (tmp, ar->as->upper[i]->value.integer,