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);
next prev 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: linkBe 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).