diff options
author | burnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-03-19 21:03:14 +0000 |
---|---|---|
committer | burnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-03-19 21:03:14 +0000 |
commit | c77badf34fffec513813579c54020e7b6a495684 (patch) | |
tree | b646ebd40aee24f252c9460c48fd6dd3ba729e86 /gcc | |
parent | c97fb132552d3ad4135f244637cde57007e23722 (diff) | |
download | gcc-c77badf34fffec513813579c54020e7b6a495684.tar.gz |
2014-03-18 Tobias Burnus <burnus@net-b.de>
PR fortran/60543
PR fortran/60283
* gfortran.h (gfc_unset_implicit_pure): New prototype.
* resolve.c (gfc_unset_implicit_pure): New.
(resolve_structure_cons, resolve_function,
pure_subroutine): Use it.
* decl.c (match_old_style_init, gfc_match_data,
match_pointer_init, variable_decl): Ditto.
* expr.c (gfc_check_pointer_assign): Ditto.
* intrinsic.c (gfc_intrinsic_sub_interface): Ditto.
* io.c (match_vtag, gfc_match_open, gfc_match_close,
match_filepos, gfc_match_inquire, gfc_match_print,
gfc_match_wait): Ditto.
* match.c (gfc_match_critical, gfc_match_stopcode,
lock_unlock_statement, sync_statement, gfc_match_allocate,
gfc_match_deallocate): Ditto.
* parse.c (decode_omp_directive): Ditto.
* symbol.c (gfc_add_save): Ditto.
2014-03-18 Tobias Burnus <burnus@net-b.de>
PR fortran/60543
PR fortran/60283
* gfortran.dg/implicit_pure_4.f90: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@208687 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/fortran/decl.c | 13 | ||||
-rw-r--r-- | gcc/fortran/expr.c | 3 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 1 | ||||
-rw-r--r-- | gcc/fortran/intrinsic.c | 5 | ||||
-rw-r--r-- | gcc/fortran/io.c | 28 | ||||
-rw-r--r-- | gcc/fortran/match.c | 27 | ||||
-rw-r--r-- | gcc/fortran/parse.c | 3 | ||||
-rw-r--r-- | gcc/fortran/resolve.c | 48 | ||||
-rw-r--r-- | gcc/fortran/symbol.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/implicit_pure_4.f90 | 22 |
12 files changed, 123 insertions, 58 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 0386d1d936b..1036716cd42 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,24 @@ +2014-03-19 Tobias Burnus <burnus@net-b.de> + + PR fortran/60543 + PR fortran/60283 + * gfortran.h (gfc_unset_implicit_pure): New prototype. + * resolve.c (gfc_unset_implicit_pure): New. + (resolve_structure_cons, resolve_function, + pure_subroutine): Use it. + * decl.c (match_old_style_init, gfc_match_data, + match_pointer_init, variable_decl): Ditto. + * expr.c (gfc_check_pointer_assign): Ditto. + * intrinsic.c (gfc_intrinsic_sub_interface): Ditto. + * io.c (match_vtag, gfc_match_open, gfc_match_close, + match_filepos, gfc_match_inquire, gfc_match_print, + gfc_match_wait): Ditto. + * match.c (gfc_match_critical, gfc_match_stopcode, + lock_unlock_statement, sync_statement, gfc_match_allocate, + gfc_match_deallocate): Ditto. + * parse.c (decode_omp_directive): Ditto. + * symbol.c (gfc_add_save): Ditto. + 2014-03-18 Janus Weil <janus@gcc.gnu.org> PR fortran/55207 diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 2d405fe9838..4048ac91353 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -510,9 +510,7 @@ match_old_style_init (const char *name) free (newdata); return MATCH_ERROR; } - - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (gfc_current_ns->proc_name); /* Mark the variable as having appeared in a data statement. */ if (!gfc_add_data (&sym->attr, sym->name, &sym->declared_at)) @@ -571,9 +569,7 @@ gfc_match_data (void) gfc_error ("DATA statement at %C is not allowed in a PURE procedure"); return MATCH_ERROR; } - - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (gfc_current_ns->proc_name); return MATCH_YES; @@ -1739,6 +1735,7 @@ match_pointer_init (gfc_expr **init, int procptr) "a PURE procedure"); return MATCH_ERROR; } + gfc_unset_implicit_pure (gfc_current_ns->proc_name); /* Match NULL() initialization. */ m = gfc_match_null (init); @@ -2046,6 +2043,10 @@ variable_decl (int elem) m = MATCH_ERROR; } + if (current_attr.flavor != FL_PARAMETER + && gfc_state_stack->state != COMP_DERIVED) + gfc_unset_implicit_pure (gfc_current_ns->proc_name); + if (m != MATCH_YES) goto cleanup; } diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index fe92c53a453..f6772047e27 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -3704,8 +3704,7 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue) } if (is_implicit_pure && gfc_impure_variable (rvalue->symtree->n.sym)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; - + gfc_unset_implicit_pure (gfc_current_ns->proc_name); if (gfc_has_vector_index (rvalue)) { diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index cd2a91323a3..14c202dd413 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2837,6 +2837,7 @@ void gfc_resolve_blocks (gfc_code *, gfc_namespace *); int gfc_impure_variable (gfc_symbol *); int gfc_pure (gfc_symbol *); int gfc_implicit_pure (gfc_symbol *); +void gfc_unset_implicit_pure (gfc_symbol *); int gfc_elemental (gfc_symbol *); bool gfc_resolve_iterator (gfc_iterator *, bool, bool); bool find_forall_index (gfc_expr *, gfc_symbol *, int); diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index 3db000b6ccf..19d46202e08 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -4404,13 +4404,16 @@ gfc_intrinsic_sub_interface (gfc_code *c, int error_flag) return MATCH_ERROR; } - if (gfc_pure (NULL) && !isym->pure) + if (!isym->pure && gfc_pure (NULL)) { gfc_error ("Subroutine call to intrinsic '%s' at %L is not PURE", name, &c->loc); return MATCH_ERROR; } + if (!isym->pure) + gfc_unset_implicit_pure (NULL); + c->resolved_sym->attr.noreturn = isym->noreturn; return MATCH_YES; diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index f2593b04e30..8d3dc46f803 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -1305,7 +1305,8 @@ match_vtag (const io_tag *tag, gfc_expr **v) return MATCH_ERROR; } - if (gfc_pure (NULL) && gfc_impure_variable (result->symtree->n.sym)) + bool impure = gfc_impure_variable (result->symtree->n.sym); + if (impure && gfc_pure (NULL)) { gfc_error ("Variable %s cannot be assigned in PURE procedure at %C", tag->name); @@ -1313,8 +1314,8 @@ match_vtag (const io_tag *tag, gfc_expr **v) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL) && gfc_impure_variable (result->symtree->n.sym)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + if (impure) + gfc_unset_implicit_pure (NULL); *v = result; return MATCH_YES; @@ -1829,8 +1830,7 @@ gfc_match_open (void) goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); warn = (open->err || open->iostat) ? true : false; @@ -2242,8 +2242,7 @@ gfc_match_close (void) goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); warn = (close->iostat || close->err) ? true : false; @@ -2410,8 +2409,7 @@ done: goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); new_st.op = op; new_st.ext.filepos = fp; @@ -3793,8 +3791,7 @@ gfc_match_print (void) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); return MATCH_YES; } @@ -3953,8 +3950,7 @@ gfc_match_inquire (void) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); new_st.block = gfc_get_code (EXEC_IOLENGTH); terminate_io (code); @@ -4006,8 +4002,7 @@ gfc_match_inquire (void) goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); if (inquire->id != NULL && inquire->pending == NULL) { @@ -4195,8 +4190,7 @@ gfc_match_wait (void) goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); new_st.op = EXEC_WAIT; new_st.ext.wait = wait; diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index 171774ce445..4c4609401a0 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -1751,8 +1751,7 @@ gfc_match_critical (void) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); if (!gfc_notify_std (GFC_STD_F2008, "CRITICAL statement at %C")) return MATCH_ERROR; @@ -2676,8 +2675,7 @@ gfc_match_stopcode (gfc_statement st) goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); if (st == ST_STOP && gfc_find_state (COMP_CRITICAL)) { @@ -2814,8 +2812,7 @@ lock_unlock_statement (gfc_statement st) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); if (gfc_option.coarray == GFC_FCOARRAY_NONE) { @@ -3008,8 +3005,7 @@ sync_statement (gfc_statement st) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); if (!gfc_notify_std (GFC_STD_F2008, "SYNC statement at %C")) return MATCH_ERROR; @@ -3479,15 +3475,15 @@ gfc_match_allocate (void) if (gfc_check_do_variable (tail->expr->symtree)) goto cleanup; - if (gfc_pure (NULL) && gfc_impure_variable (tail->expr->symtree->n.sym)) + bool impure = gfc_impure_variable (tail->expr->symtree->n.sym); + if (impure && gfc_pure (NULL)) { gfc_error ("Bad allocate-object at %C for a PURE procedure"); goto cleanup; } - if (gfc_implicit_pure (NULL) - && gfc_impure_variable (tail->expr->symtree->n.sym)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + if (impure) + gfc_unset_implicit_pure (NULL); if (tail->expr->ts.deferred) { @@ -3868,14 +3864,15 @@ gfc_match_deallocate (void) sym = tail->expr->symtree->n.sym; - if (gfc_pure (NULL) && gfc_impure_variable (sym)) + bool impure = gfc_impure_variable (sym); + if (impure && gfc_pure (NULL)) { gfc_error ("Illegal allocate-object at %C for a PURE procedure"); goto cleanup; } - if (gfc_implicit_pure (NULL) && gfc_impure_variable (sym)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + if (impure) + gfc_unset_implicit_pure (NULL); if (gfc_is_coarray (tail->expr) && gfc_find_state (COMP_DO_CONCURRENT)) diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index d9af60e578b..0faf47a0041 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -550,8 +550,7 @@ decode_omp_directive (void) return ST_NONE; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); old_locus = gfc_current_locus; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index bcdfcadd3d1..ac58167558b 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -1328,9 +1328,10 @@ resolve_structure_cons (gfc_expr *expr, int init) } /* F2003, C1272 (3). */ - if (gfc_pure (NULL) && cons->expr->expr_type == EXPR_VARIABLE - && (gfc_impure_variable (cons->expr->symtree->n.sym) - || gfc_is_coindexed (cons->expr))) + bool impure = cons->expr->expr_type == EXPR_VARIABLE + && (gfc_impure_variable (cons->expr->symtree->n.sym) + || gfc_is_coindexed (cons->expr)); + if (impure && gfc_pure (NULL)) { t = false; gfc_error ("Invalid expression in the structure constructor for " @@ -1338,12 +1339,8 @@ resolve_structure_cons (gfc_expr *expr, int init) comp->name, &cons->expr->where); } - if (gfc_implicit_pure (NULL) - && cons->expr->expr_type == EXPR_VARIABLE - && (gfc_impure_variable (cons->expr->symtree->n.sym) - || gfc_is_coindexed (cons->expr))) - gfc_current_ns->proc_name->attr.implicit_pure = 0; - + if (impure) + gfc_unset_implicit_pure (NULL); } return t; @@ -3006,8 +3003,7 @@ resolve_function (gfc_expr *expr) t = false; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); } /* Functions without the RECURSIVE attribution are not allowed to @@ -3072,8 +3068,7 @@ pure_subroutine (gfc_code *c, gfc_symbol *sym) gfc_error ("Subroutine call to '%s' at %L is not PURE", sym->name, &c->loc); - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); } @@ -13927,6 +13922,33 @@ gfc_implicit_pure (gfc_symbol *sym) } +void +gfc_unset_implicit_pure (gfc_symbol *sym) +{ + gfc_namespace *ns; + + if (sym == NULL) + { + /* Check if the current procedure is implicit_pure. Walk up + the procedure list until we find a procedure. */ + for (ns = gfc_current_ns; ns; ns = ns->parent) + { + sym = ns->proc_name; + if (sym == NULL) + return; + + if (sym->attr.flavor == FL_PROCEDURE) + break; + } + } + + if (sym->attr.flavor == FL_PROCEDURE) + sym->attr.implicit_pure = 0; + else + sym->attr.pure = 0; +} + + /* Test whether the current procedure is elemental or not. */ int diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 66668720b7b..19d792e0862 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -1114,8 +1114,8 @@ gfc_add_save (symbol_attribute *attr, save_state s, const char *name, return false; } - if (s == SAVE_EXPLICIT && gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + if (s == SAVE_EXPLICIT) + gfc_unset_implicit_pure (NULL); if (s == SAVE_EXPLICIT && attr->save == SAVE_EXPLICIT) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d0f56cdbca1..839aed7bcaf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-03-19 Tobias Burnus <burnus@net-b.de> + + PR fortran/60543 + PR fortran/60283 + * gfortran.dg/implicit_pure_4.f90: New. + 2014-03-19 Paolo Carlini <paolo.carlini@oracle.com> PR c++/51474 diff --git a/gcc/testsuite/gfortran.dg/implicit_pure_4.f90 b/gcc/testsuite/gfortran.dg/implicit_pure_4.f90 new file mode 100644 index 00000000000..8563dd72108 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/implicit_pure_4.f90 @@ -0,0 +1,22 @@ +! { dg-do compile } +! +! PR fortran/60543 +! PR fortran/60283 +! +module m +contains + REAL(8) FUNCTION random() + CALL RANDOM_NUMBER(random) + END FUNCTION random + REAL(8) FUNCTION random2() + block + block + block + CALL RANDOM_NUMBER(random2) + end block + end block + end block + END FUNCTION random2 +end module m + +! { dg-final { scan-module-absence "m" "IMPLICIT_PURE" } } |