public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "kargl at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug fortran/96255] [F2018] Implement optional type spec for index in DO CONCURRENT
Date: Wed, 22 Jul 2020 18:25:15 +0000	[thread overview]
Message-ID: <bug-96255-4-hmDpX234cz@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-96255-4@http.gcc.gnu.org/bugzilla/>

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96255

--- Comment #8 from kargl at gcc dot gnu.org ---
New patch.  This adds a bool component to gfc_forall_iterator so
that an iterator with an index-name that shadows a variable from
outer scope can be marked.  Shadowing only occurs when a type-spec
causes the kind type parameter to differ from the kind type 
parameter of the outer scope variable.

A fatal error occurs if shadowing is found.  Someone needs to
wlak the forall block (and by extension the do concurrent block)
updating references to the outer scope variable to be those of
the shadow variable.

It might be beneficial to introduce a namespace for forall and
do concurrent, but I won't go down that path.

Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h      (revision 280157)
+++ gcc/fortran/gfortran.h      (working copy)
@@ -2525,6 +2525,8 @@ gfc_dt;
 typedef struct gfc_forall_iterator
 {
   gfc_expr *var, *start, *end, *stride;
+  /* index-name shadows a variable from outer scope.  */
+  bool shadow;
   struct gfc_forall_iterator *next;
 }
 gfc_forall_iterator;
Index: gcc/fortran/match.c
===================================================================
--- gcc/fortran/match.c (revision 280157)
+++ gcc/fortran/match.c (working copy)
@@ -2381,7 +2381,10 @@ cleanup:
 }


-/* Match the header of a FORALL statement.  */
+/* Match the header of a FORALL statement.  In F2008 and F2018, the form of
+   the header is 
+   ([ type-spec :: ] concurrent-control-list [, scalar-mask-expr ] )
+   where type-spec is INTEGER.  */

 static match
 match_forall_header (gfc_forall_iterator **phead, gfc_expr **mask)
@@ -2389,6 +2392,9 @@ match_forall_header (gfc_forall_iterator **phead, gfc_
   gfc_forall_iterator *head, *tail, *new_iter;
   gfc_expr *msk;
   match m;
+  gfc_typespec ts;
+  bool seen_ts = false;
+  locus loc;

   gfc_gobble_whitespace ();

@@ -2398,12 +2404,76 @@ match_forall_header (gfc_forall_iterator **phead, gfc_
   if (gfc_match_char ('(') != MATCH_YES)
     return MATCH_NO;

+  /* Check for an optional type-spec.  */
+  gfc_clear_ts (&ts);
+  loc = gfc_current_locus;
+  m = gfc_match_type_spec (&ts);
+  if (m == MATCH_YES)
+    {
+      seen_ts = (gfc_match (" ::") == MATCH_YES);
+
+      if (seen_ts)
+       {
+         if (!gfc_notify_std (GFC_STD_F2008, "FORALL or DO CONCURRENT "
+                              "construct includes type specification "
+                              "at %L", &loc))
+           goto cleanup;
+
+         if (ts.type != BT_INTEGER)
+           {
+             gfc_error ("Type-spec at %L must be an INTEGER type", &loc);
+             goto cleanup;
+           }
+       }
+    }
+  else if (m == MATCH_ERROR)
+    goto syntax;
+
   m = match_forall_iterator (&new_iter);
   if (m == MATCH_ERROR)
     goto cleanup;
   if (m == MATCH_NO)
     goto syntax;

+  if (seen_ts)
+    {
+      char *name;
+      gfc_expr *v;
+      gfc_symtree *st;
+
+      /* If index-name does not have a type and type spec, then update the
+        type spec in both the expr and symtree.  Otherwise, create a new
+        shadow index-name.  */
+      new_iter->shadow = false;
+      v = new_iter->var;
+      if (v->ts.type == BT_UNKNOWN)
+       {
+         v->ts.type = v->symtree->n.sym->ts.type = BT_INTEGER;
+         v->ts.kind = v->symtree->n.sym->ts.kind = ts.kind;
+       }
+      else if (v->ts.kind != ts.kind)
+       {
+         name = (char *) alloca (strlen (v->symtree->name) + 2);
+         strcpy (name, "_");
+         strcat (name, v->symtree->name);
+         if (gfc_get_sym_tree (name, NULL, &st, false) != 0)
+           gfc_internal_error ("whoops");
+
+         v = gfc_get_expr ();
+         v->where = gfc_current_locus;
+         v->expr_type = EXPR_VARIABLE;
+         v->ts.type = st->n.sym->ts.type = ts.type;
+         v->ts.kind = st->n.sym->ts.kind = ts.kind;
+         st->n.sym->forall_index = true;
+         v->symtree = st;
+         gfc_replace_expr (new_iter->var, v);
+         new_iter->shadow = true;
+       }
+      gfc_convert_type (new_iter->start, &ts, 1);
+      gfc_convert_type (new_iter->end, &ts, 1);
+      gfc_convert_type (new_iter->stride, &ts, 1);
+    }
+
   head = tail = new_iter;

   for (;;)
@@ -2417,6 +2487,44 @@ match_forall_header (gfc_forall_iterator **phead, gfc_

       if (m == MATCH_YES)
        {
+         if (seen_ts)
+           {
+             char *name;
+             gfc_expr *v;
+             gfc_symtree *st;
+
+             new_iter->shadow = false;
+             v = new_iter->var;
+             if (v->ts.type == BT_UNKNOWN)
+               {
+                 v->ts.type = v->symtree->n.sym->ts.type = BT_INTEGER;
+                 v->ts.kind = v->symtree->n.sym->ts.kind = ts.kind;
+               }
+             else if (v->ts.kind != ts.kind)
+               {
+                 name = (char *) alloca (strlen (v->symtree->name) + 2);
+                 strcpy (name, "_");
+                 strcat (name, v->symtree->name);
+                 if (gfc_get_sym_tree (name, NULL, &st, false) != 0)
+                   gfc_internal_error ("whoops");
+
+                 v = gfc_get_expr ();
+                 v->expr_type = EXPR_VARIABLE;
+                 v->ts.type = ts.type;
+                 v->ts.kind = ts.kind;
+                 v->where = gfc_current_locus;
+                 st->n.sym->ts.type = ts.type;
+                 st->n.sym->ts.kind = ts.kind;
+                 st->n.sym->forall_index = true;
+                 v->symtree = st;
+                 gfc_replace_expr (new_iter->var, v);
+                 new_iter->shadow = true;
+               }
+             gfc_convert_type (new_iter->start, &ts, 1);
+             gfc_convert_type (new_iter->end, &ts, 1);
+             gfc_convert_type (new_iter->stride, &ts, 1);
+           }
+
          tail->next = new_iter;
          tail = new_iter;
          continue;
Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c       (revision 280157)
+++ gcc/fortran/resolve.c       (working copy)
@@ -10322,11 +10322,10 @@ static void
 gfc_resolve_assign_in_forall (gfc_code *code, int nvar, gfc_expr **var_expr)
 {
   int n;
+  gfc_symbol *forall_index;

   for (n = 0; n < nvar; n++)
     {
-      gfc_symbol *forall_index;
-
       forall_index = var_expr[n]->symtree->n.sym;

       /* Check whether the assignment target is one of the FORALL index
@@ -10475,8 +10474,10 @@ gfc_count_forall_iterators (gfc_code *code)
 }


-/* Given a FORALL construct, first resolve the FORALL iterator, then call
-   gfc_resolve_forall_body to resolve the FORALL body.  */
+/* Given a FORALL construct.
+   1) Resolve the FORALL iterator.
+   2) Check for shadow index-name(s) and update code block.
+   3) call gfc_resolve_forall_body to resolve the FORALL body.  */

 static void
 gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
@@ -10486,6 +10487,7 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns,
   static int nvar = 0;
   int i, old_nvar, tmp;
   gfc_forall_iterator *fa;
+  bool shadow = false;

   old_nvar = nvar;

@@ -10503,8 +10505,9 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns,
       var_expr = XCNEWVEC (gfc_expr *, total_var);
     }

-  /* The information about FORALL iterator, including FORALL indices start,
end
-     and stride.  An outer FORALL indice cannot appear in start, end or
stride.  */
+  /* The information about FORALL iterator, including FORALL indices start,
+     end and stride.  An outer FORALL indice cannot appear in start, end or
+     stride.  Check for a shadow index-name.  */
   for (fa = code->ext.forall_iterator; fa; fa = fa->next)
     {
       /* Fortran 20008: C738 (R753).  */
@@ -10524,6 +10527,9 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns,
                        "with this name %L", &fa->var->where);
        }

+      if (fa->shadow)
+       shadow = true;
+
       /* Record the current FORALL index.  */
       var_expr[nvar] = gfc_copy_expr (fa->var);

@@ -10532,6 +10538,12 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns,
       /* No memory leak.  */
       gcc_assert (nvar <= total_var);
     }
+
+  /* Need to walk the code and replace references to the index-name with
+     references to the shadow index-name.  */
+  if (shadow)
+    gfc_fatal_error ("An index-name shadows a variable from outer scope, "
+                    "which causes a wrong-code bug.");

   /* Resolve the FORALL body.  */
   gfc_resolve_forall_body (code, nvar, var_expr);

  parent reply	other threads:[~2020-07-22 18:25 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-21  0:47 [Bug fortran/96255] New: [F2018] Implement option type spec for index " jvdelisle at charter dot net
2020-07-21  4:24 ` [Bug fortran/96255] [F2018] Implement optional type spec for index in " kargl at gcc dot gnu.org
2020-07-21  5:53 ` kargl at gcc dot gnu.org
2020-07-21  5:57 ` kargl at gcc dot gnu.org
2020-07-21 14:34 ` dominiq at lps dot ens.fr
2020-07-21 19:41 ` jvdelisle at charter dot net
2020-07-21 19:44 ` jvdelisle at charter dot net
2020-07-21 20:25 ` sgk at troutmask dot apl.washington.edu
2020-07-22  6:29 ` kargl at gcc dot gnu.org
2020-07-22 18:25 ` kargl at gcc dot gnu.org [this message]
2021-11-11 21:01 ` anlauf at gcc dot gnu.org
2023-02-02 20:11 ` Boyce at engineer dot com
2023-02-03  7:25 ` kargl at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-96255-4-hmDpX234cz@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).