re PR fortran/48788 (ICE: SIGSEGV in resolve_global_procedure (resolve.c:2190) on...
[platform/upstream/gcc.git] / gcc / fortran / resolve.c
index a4a77ac..144d308 100644 (file)
@@ -160,7 +160,10 @@ resolve_procedure_interface (gfc_symbol *sym)
        resolve_intrinsic (ifc, &ifc->declared_at);
 
       if (ifc->result)
-       sym->ts = ifc->result->ts;
+       {
+         sym->ts = ifc->result->ts;
+         sym->result = sym;
+       }
       else   
        sym->ts = ifc->ts;
       sym->ts.interface = ifc;
@@ -339,14 +342,30 @@ resolve_formal_arglist (gfc_symbol *proc)
          && sym->attr.flavor != FL_PROCEDURE)
        {
          if (proc->attr.function && sym->attr.intent != INTENT_IN)
-           gfc_error ("Argument '%s' of pure function '%s' at %L must be "
-                      "INTENT(IN)", sym->name, proc->name,
-                      &sym->declared_at);
+           {
+             if (sym->attr.value)
+               gfc_notify_std (GFC_STD_F2008, "Fortran 2008: Argument '%s' "
+                               "of pure function '%s' at %L with VALUE "
+                               "attribute but without INTENT(IN)", sym->name,
+                               proc->name, &sym->declared_at);
+             else
+               gfc_error ("Argument '%s' of pure function '%s' at %L must be "
+                          "INTENT(IN) or VALUE", sym->name, proc->name,
+                          &sym->declared_at);
+           }
 
          if (proc->attr.subroutine && sym->attr.intent == INTENT_UNKNOWN)
-           gfc_error ("Argument '%s' of pure subroutine '%s' at %L must "
-                      "have its INTENT specified", sym->name, proc->name,
-                      &sym->declared_at);
+           {
+             if (sym->attr.value)
+               gfc_notify_std (GFC_STD_F2008, "Fortran 2008: Argument '%s' "
+                               "of pure subroutine '%s' at %L with VALUE "
+                               "attribute but without INTENT", sym->name,
+                               proc->name, &sym->declared_at);
+             else
+               gfc_error ("Argument '%s' of pure subroutine '%s' at %L must "
+                      "have its INTENT specified or have the VALUE "
+                      "attribute", sym->name, proc->name, &sym->declared_at);
+           }
        }
 
       if (proc->attr.implicit_pure && !sym->attr.pointer
@@ -500,7 +519,7 @@ resolve_contained_fntype (gfc_symbol *sym, gfc_namespace *ns)
   if (sym->result->ts.type == BT_CHARACTER)
     {
       gfc_charlen *cl = sym->result->ts.u.cl;
-      if (!cl || !cl->length)
+      if ((!cl || !cl->length) && !sym->result->ts.deferred)
        {
          /* See if this is a module-procedure and adapt error message
             accordingly.  */
@@ -1072,7 +1091,7 @@ resolve_structure_cons (gfc_expr *expr, int init)
                    cl2->next = cl->next;
 
                  gfc_free_expr (cl->length);
-                 gfc_free (cl);
+                 free (cl);
                }
 
              cons->expr->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
@@ -2168,7 +2187,7 @@ resolve_global_procedure (gfc_symbol *sym, locus *where,
 
          /* F2003, 12.3.1.1 (3c); F2008, 12.4.2.2 (3c)  */
          if (sym->ts.type == BT_CHARACTER && sym->attr.if_source != IFSRC_IFBODY
-             && def_sym->ts.u.cl->length != NULL)
+             && def_sym->ts.type == BT_CHARACTER && def_sym->ts.u.cl->length != NULL)
            {
              gfc_charlen *cl = sym->ts.u.cl;
 
@@ -2990,6 +3009,7 @@ resolve_function (gfc_expr *expr)
       && sym->ts.u.cl
       && sym->ts.u.cl->length == NULL
       && !sym->attr.dummy
+      && !sym->ts.deferred
       && expr->value.function.esym == NULL
       && !sym->attr.contained)
     {
@@ -4137,6 +4157,7 @@ check_dimension (int i, gfc_array_ref *ar, gfc_array_spec *as)
   switch (ar->dimen_type[i])
     {
     case DIMEN_VECTOR:
+    case DIMEN_THIS_IMAGE:
       break;
 
     case DIMEN_STAR:
@@ -4304,7 +4325,8 @@ compare_spec_to_ref (gfc_array_ref *ar)
   if (ar->codimen != 0)
     for (i = as->rank; i < as->rank + as->corank; i++)
       {
-       if (ar->dimen_type[i] != DIMEN_ELEMENT && !ar->in_allocate)
+       if (ar->dimen_type[i] != DIMEN_ELEMENT && !ar->in_allocate
+           && ar->dimen_type[i] != DIMEN_THIS_IMAGE)
          {
            gfc_error ("Coindex of codimension %d must be a scalar at %L",
                       i + 1 - as->rank, &ar->where);
@@ -4314,6 +4336,14 @@ compare_spec_to_ref (gfc_array_ref *ar)
          return FAILURE;
       }
 
+  if (as->corank && ar->codimen == 0)
+    {
+      int n;
+      ar->codimen = as->corank;
+      for (n = ar->dimen; n < ar->dimen + ar->codimen; n++)
+       ar->dimen_type[n] = DIMEN_THIS_IMAGE;
+    }
+
   return SUCCESS;
 }
 
@@ -5164,7 +5194,7 @@ check_host_association (gfc_expr *e)
              for (n = 0; n < e->rank; n++)
                mpz_clear (e->shape[n]);
 
-             gfc_free (e->shape);
+             free (e->shape);
            }
 
          /* Give the expression the right symtree!  */
@@ -5874,14 +5904,12 @@ resolve_typebound_subroutine (gfc_code *code)
 
   /* Deal with typebound operators for CLASS objects.  */
   expr = code->expr1->value.compcall.base_object;
-  if (expr && expr->symtree->n.sym->ts.type == BT_CLASS
-       && code->expr1->value.compcall.name)
+  if (expr && expr->ts.type == BT_CLASS && code->expr1->value.compcall.name)
     {
       /* Since the typebound operators are generic, we have to ensure
         that any delays in resolution are corrected and that the vtab
         is present.  */
-      ts = expr->symtree->n.sym->ts;
-      declared = ts.u.derived;
+      declared = expr->ts.u.derived;
       c = gfc_find_component (declared, "_vptr", true, true);
       if (c->ts.u.derived == NULL)
        c->ts.u.derived = gfc_find_derived_vtab (declared);
@@ -5892,7 +5920,7 @@ resolve_typebound_subroutine (gfc_code *code)
       /* Use the generic name if it is there.  */
       name = name ? name : code->expr1->value.function.esym->name;
       code->expr1->symtree = expr->symtree;
-      expr->symtree->n.sym->ts.u.derived = declared;
+      code->expr1->ref = gfc_copy_ref (expr->ref);
       gfc_add_vptr_component (code->expr1);
       gfc_add_component_ref (code->expr1, name);
       code->expr1->value.function.esym = NULL;
@@ -6608,6 +6636,7 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code)
 {
   int i, pointer, allocatable, dimension, is_abstract;
   int codimension;
+  bool coindexed;
   symbol_attribute attr;
   gfc_ref *ref, *ref2;
   gfc_expr *e2;
@@ -6665,18 +6694,32 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code)
          codimension = sym->attr.codimension;
        }
 
+      coindexed = false;
+
       for (ref = e->ref; ref; ref2 = ref, ref = ref->next)
        {
          switch (ref->type)
            {
              case REF_ARRAY:
+                if (ref->u.ar.codimen > 0)
+                 {
+                   int n;
+                   for (n = ref->u.ar.dimen;
+                        n < ref->u.ar.dimen + ref->u.ar.codimen; n++)
+                     if (ref->u.ar.dimen_type[n] != DIMEN_THIS_IMAGE)
+                       {
+                         coindexed = true;
+                         break;
+                       }
+                  }
+
                if (ref->next != NULL)
                  pointer = 0;
                break;
 
              case REF_COMPONENT:
                /* F2008, C644.  */
-               if (gfc_is_coindexed (e))
+               if (coindexed)
                  {
                    gfc_error ("Coindexed allocatable object at %L",
                               &e->where);
@@ -6830,12 +6873,14 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code)
 
   ar = &ref2->u.ar;
 
-  if (codimension && ar->codimen == 0)
-    {
-      gfc_error ("Coarray specification required in ALLOCATE statement "
-                "at %L", &e->where);
-      goto failure;
-    }
+  if (codimension)
+    for (i = ar->dimen; i < ar->dimen + ar->codimen; i++)
+      if (ar->dimen_type[i] == DIMEN_THIS_IMAGE)
+       {
+         gfc_error ("Coarray specification required in ALLOCATE statement "
+                    "at %L", &e->where);
+         goto failure;
+       }
 
   for (i = 0; i < ar->dimen; i++)
     {
@@ -6858,6 +6903,7 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code)
        case DIMEN_UNKNOWN:
        case DIMEN_VECTOR:
        case DIMEN_STAR:
+       case DIMEN_THIS_IMAGE:
          gfc_error ("Bad array specification in ALLOCATE statement at %L",
                     &e->where);
          goto failure;
@@ -6916,12 +6962,6 @@ check_symbols:
     }
 
 success:
-  if (e->ts.deferred)
-    {
-      gfc_error ("Support for entity at %L with deferred type parameter "
-                "not yet implemented", &e->where);
-      return FAILURE;
-    }
   return SUCCESS;
 
 failure:
@@ -8079,6 +8119,14 @@ resolve_transfer (gfc_code *code)
          return;
        }
 
+      /* F08:C935.  */
+      if (ts->u.derived->attr.proc_pointer_comp)
+       {
+         gfc_error ("Data transfer element at %L cannot have "
+                    "procedure pointer components", &code->loc);
+         return;
+       }
+
       if (ts->u.derived->attr.alloc_comp)
        {
          gfc_error ("Data transfer element at %L cannot have "
@@ -8565,7 +8613,7 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
       total_var = gfc_count_forall_iterators (code);
 
       /* Allocate VAR_EXPR with NUMBER_OF_FORALL_INDEX elements.  */
-      var_expr = (gfc_expr **) gfc_getmem (total_var * sizeof (gfc_expr *));
+      var_expr = XCNEWVEC (gfc_expr *, total_var);
     }
 
   /* The information about FORALL iterator, including FORALL index start, end
@@ -8610,7 +8658,7 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
       gcc_assert (forall_save == 0);
 
       /* VAR_EXPR is not needed any more.  */
-      gfc_free (var_expr);
+      free (var_expr);
       total_var = 0;
     }
 }
@@ -10067,7 +10115,8 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
   /* Reject illegal initializers.  */
   if (!sym->mark && sym->value)
     {
-      if (sym->attr.allocatable)
+      if (sym->attr.allocatable || (sym->ts.type == BT_CLASS
+                                   && CLASS_DATA (sym)->attr.allocatable))
        gfc_error ("Allocatable '%s' at %L cannot have an initializer",
                   sym->name, &sym->declared_at);
       else if (sym->attr.external)
@@ -10133,7 +10182,7 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
      the host.  */
   if (!(sym->ns->parent
        && sym->ns->parent->proc_name->attr.flavor == FL_MODULE)
-      && gfc_check_access(sym->attr.access, sym->ns->default_access))
+      && gfc_check_symbol_access (sym))
     {
       gfc_interface *iface;
 
@@ -10142,8 +10191,7 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
          if (arg->sym
              && arg->sym->ts.type == BT_DERIVED
              && !arg->sym->ts.u.derived->attr.use_assoc
-             && !gfc_check_access (arg->sym->ts.u.derived->attr.access,
-                                   arg->sym->ts.u.derived->ns->default_access)
+             && !gfc_check_symbol_access (arg->sym->ts.u.derived)
              && gfc_notify_std (GFC_STD_F2003, "Fortran 2003: '%s' is of a "
                                 "PRIVATE type and cannot be a dummy argument"
                                 " of '%s', which is PUBLIC at %L",
@@ -10165,8 +10213,7 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
              if (arg->sym
                  && arg->sym->ts.type == BT_DERIVED
                  && !arg->sym->ts.u.derived->attr.use_assoc
-                 && !gfc_check_access (arg->sym->ts.u.derived->attr.access,
-                                       arg->sym->ts.u.derived->ns->default_access)
+                 && !gfc_check_symbol_access (arg->sym->ts.u.derived)
                  && gfc_notify_std (GFC_STD_F2003, "Fortran 2003: Procedure "
                                     "'%s' in PUBLIC interface '%s' at %L "
                                     "takes dummy arguments of '%s' which is "
@@ -10190,8 +10237,7 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
              if (arg->sym
                  && arg->sym->ts.type == BT_DERIVED
                  && !arg->sym->ts.u.derived->attr.use_assoc
-                 && !gfc_check_access (arg->sym->ts.u.derived->attr.access,
-                                       arg->sym->ts.u.derived->ns->default_access)
+                 && !gfc_check_symbol_access (arg->sym->ts.u.derived)
                  && gfc_notify_std (GFC_STD_F2003, "Fortran 2003: Procedure "
                                     "'%s' in PUBLIC interface '%s' at %L "
                                     "takes dummy arguments of '%s' which is "
@@ -10234,6 +10280,14 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
       return FAILURE;
     }
 
+  if (sym->attr.proc == PROC_ST_FUNCTION
+      && (sym->attr.allocatable || sym->attr.pointer))
+    {
+      gfc_error ("Statement function '%s' at %L may not have pointer or "
+                "allocatable attribute", sym->name, &sym->declared_at);
+      return FAILURE;
+    }
+
   /* 5.1.1.5 of the Standard: A function name declared with an asterisk
      char-len-param shall not be array-valued, pointer-valued, recursive
      or pure.  ....snip... A character value of * may only be used in the
@@ -10267,8 +10321,11 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
        }
 
       /* Appendix B.2 of the standard.  Contained functions give an
-        error anyway.  Fixed-form is likely to be F77/legacy.  */
-      if (!sym->attr.contained && gfc_current_form != FORM_FIXED)
+        error anyway.  Fixed-form is likely to be F77/legacy. Deferred
+        character length is an F2003 feature.  */
+      if (!sym->attr.contained
+           && gfc_current_form != FORM_FIXED
+           && !sym->ts.deferred)
        gfc_notify_std (GFC_STD_F95_OBS, "Obsolescent feature: "
                        "CHARACTER(*) function '%s' at %L",
                        sym->name, &sym->declared_at);
@@ -11605,7 +11662,8 @@ resolve_fl_derived (gfc_symbol *sym)
          return FAILURE;
        }
 
-      if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer)
+      if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
+           && !c->ts.deferred)
        {
         if (c->ts.u.cl->length == NULL
             || (resolve_charlen (c->ts.u.cl) == FAILURE)
@@ -11619,13 +11677,21 @@ resolve_fl_derived (gfc_symbol *sym)
           }
        }
 
+      if (c->ts.type == BT_CHARACTER && c->ts.deferred
+         && !c->attr.pointer && !c->attr.allocatable)
+       {
+         gfc_error ("Character component '%s' of '%s' at %L with deferred "
+                    "length must be a POINTER or ALLOCATABLE",
+                    c->name, sym->name, &c->loc);
+         return FAILURE;
+       }
+
       if (c->ts.type == BT_DERIVED
          && sym->component_access != ACCESS_PRIVATE
-         && gfc_check_access (sym->attr.access, sym->ns->default_access)
+         && gfc_check_symbol_access (sym)
          && !is_sym_host_assoc (c->ts.u.derived, sym->ns)
          && !c->ts.u.derived->attr.use_assoc
-         && !gfc_check_access (c->ts.u.derived->attr.access,
-                               c->ts.u.derived->ns->default_access)
+         && !gfc_check_symbol_access (c->ts.u.derived)
          && gfc_notify_std (GFC_STD_F2003, "Fortran 2003: the component '%s' "
                             "is a PRIVATE type and cannot be a component of "
                             "'%s', which is PUBLIC at %L", c->name,
@@ -11789,14 +11855,13 @@ resolve_fl_namelist (gfc_symbol *sym)
     }
 
   /* Reject PRIVATE objects in a PUBLIC namelist.  */
-  if (gfc_check_access(sym->attr.access, sym->ns->default_access))
+  if (gfc_check_symbol_access (sym))
     {
       for (nl = sym->namelist; nl; nl = nl->next)
        {
          if (!nl->sym->attr.use_assoc
              && !is_sym_host_assoc (nl->sym, sym->ns)
-             && !gfc_check_access(nl->sym->attr.access,
-                               nl->sym->ns->default_access))
+             && !gfc_check_symbol_access (nl->sym))
            {
              gfc_error ("NAMELIST object '%s' was declared PRIVATE and "
                         "cannot be member of PUBLIC namelist '%s' at %L",
@@ -11817,9 +11882,7 @@ resolve_fl_namelist (gfc_symbol *sym)
          /* Types with private components that are defined in the same module.  */
          if (nl->sym->ts.type == BT_DERIVED
              && !is_sym_host_assoc (nl->sym->ts.u.derived, sym->ns)
-             && !gfc_check_access (nl->sym->ts.u.derived->attr.private_comp
-                                       ? ACCESS_PRIVATE : ACCESS_UNKNOWN,
-                                       nl->sym->ns->default_access))
+             && nl->sym->ts.u.derived->attr.private_comp)
            {
              gfc_error ("NAMELIST object '%s' has PRIVATE components and "
                         "cannot be a member of PUBLIC namelist '%s' at %L",
@@ -12192,8 +12255,7 @@ resolve_symbol (gfc_symbol *sym)
        return;
 
       gfc_find_symbol (sym->ts.u.derived->name, sym->ns, 1, &ds);
-      if (!ds && sym->attr.function
-           && gfc_check_access (sym->attr.access, sym->ns->default_access))
+      if (!ds && sym->attr.function && gfc_check_symbol_access (sym))
        {
          symtree = gfc_new_symtree (&sym->ns->sym_root,
                                     sym->ts.u.derived->name);
@@ -12209,9 +12271,8 @@ resolve_symbol (gfc_symbol *sym)
   if (sym->ts.type == BT_DERIVED
       && sym->ns->proc_name && sym->ns->proc_name->attr.flavor == FL_MODULE
       && !sym->ts.u.derived->attr.use_assoc
-      && gfc_check_access (sym->attr.access, sym->ns->default_access)
-      && !gfc_check_access (sym->ts.u.derived->attr.access,
-                           sym->ts.u.derived->ns->default_access)
+      && gfc_check_symbol_access (sym)
+      && !gfc_check_symbol_access (sym->ts.u.derived)
       && gfc_notify_std (GFC_STD_F2003, "Fortran 2003: PUBLIC %s '%s' at %L "
                         "of PRIVATE derived type '%s'",
                         (sym->attr.flavor == FL_PARAMETER) ? "parameter"
@@ -12468,18 +12529,18 @@ check_data_variable (gfc_data_variable *var, locus *where)
 
   has_pointer = sym->attr.pointer;
 
+  if (gfc_is_coindexed (e))
+    {
+      gfc_error ("DATA element '%s' at %L cannot have a coindex", sym->name,
+                where);
+      return FAILURE;
+    }
+
   for (ref = e->ref; ref; ref = ref->next)
     {
       if (ref->type == REF_COMPONENT && ref->u.c.component->attr.pointer)
        has_pointer = 1;
 
-      if (ref->type == REF_ARRAY && ref->u.ar.codimen)
-       {
-         gfc_error ("DATA element '%s' at %L cannot have a coindex",
-                    sym->name, where);
-         return FAILURE;
-       }
-
       if (has_pointer
            && ref->type == REF_ARRAY
            && ref->u.ar.type != AR_FULL)
@@ -13138,7 +13199,7 @@ resolve_equivalence (gfc_equiv *eq)
                  e->ts.u.cl = NULL;
                }
              ref = ref->next;
-             gfc_free (mem);
+             free (mem);
            }
 
          /* Any further ref is an error.  */
@@ -13322,9 +13383,8 @@ resolve_fntype (gfc_namespace *ns)
 
   if (sym->ts.type == BT_DERIVED && !sym->ts.u.derived->attr.use_assoc
       && !sym->attr.contained
-      && !gfc_check_access (sym->ts.u.derived->attr.access,
-                           sym->ts.u.derived->ns->default_access)
-      && gfc_check_access (sym->attr.access, sym->ns->default_access))
+      && !gfc_check_symbol_access (sym->ts.u.derived)
+      && gfc_check_symbol_access (sym))
     {
       gfc_notify_std (GFC_STD_F2003, "Fortran 2003: PUBLIC function '%s' at "
                      "%L of PRIVATE type '%s'", sym->name,