Commit ccd7751b by Tobias Burnus Committed by Tobias Burnus

re PR fortran/60543 (Function with side effect removed by the optimizer.)

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.

From-SVN: r208687
parent 7d092805
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> 2014-03-18 Janus Weil <janus@gcc.gnu.org>
PR fortran/55207 PR fortran/55207
......
...@@ -510,9 +510,7 @@ match_old_style_init (const char *name) ...@@ -510,9 +510,7 @@ match_old_style_init (const char *name)
free (newdata); free (newdata);
return MATCH_ERROR; return MATCH_ERROR;
} }
gfc_unset_implicit_pure (gfc_current_ns->proc_name);
if (gfc_implicit_pure (NULL))
gfc_current_ns->proc_name->attr.implicit_pure = 0;
/* Mark the variable as having appeared in a data statement. */ /* Mark the variable as having appeared in a data statement. */
if (!gfc_add_data (&sym->attr, sym->name, &sym->declared_at)) if (!gfc_add_data (&sym->attr, sym->name, &sym->declared_at))
...@@ -571,9 +569,7 @@ gfc_match_data (void) ...@@ -571,9 +569,7 @@ gfc_match_data (void)
gfc_error ("DATA statement at %C is not allowed in a PURE procedure"); gfc_error ("DATA statement at %C is not allowed in a PURE procedure");
return MATCH_ERROR; return MATCH_ERROR;
} }
gfc_unset_implicit_pure (gfc_current_ns->proc_name);
if (gfc_implicit_pure (NULL))
gfc_current_ns->proc_name->attr.implicit_pure = 0;
return MATCH_YES; return MATCH_YES;
...@@ -1739,6 +1735,7 @@ match_pointer_init (gfc_expr **init, int procptr) ...@@ -1739,6 +1735,7 @@ match_pointer_init (gfc_expr **init, int procptr)
"a PURE procedure"); "a PURE procedure");
return MATCH_ERROR; return MATCH_ERROR;
} }
gfc_unset_implicit_pure (gfc_current_ns->proc_name);
/* Match NULL() initialization. */ /* Match NULL() initialization. */
m = gfc_match_null (init); m = gfc_match_null (init);
...@@ -2046,6 +2043,10 @@ variable_decl (int elem) ...@@ -2046,6 +2043,10 @@ variable_decl (int elem)
m = MATCH_ERROR; 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) if (m != MATCH_YES)
goto cleanup; goto cleanup;
} }
......
...@@ -3704,8 +3704,7 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue) ...@@ -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)) 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)) if (gfc_has_vector_index (rvalue))
{ {
......
...@@ -2837,6 +2837,7 @@ void gfc_resolve_blocks (gfc_code *, gfc_namespace *); ...@@ -2837,6 +2837,7 @@ void gfc_resolve_blocks (gfc_code *, gfc_namespace *);
int gfc_impure_variable (gfc_symbol *); int gfc_impure_variable (gfc_symbol *);
int gfc_pure (gfc_symbol *); int gfc_pure (gfc_symbol *);
int gfc_implicit_pure (gfc_symbol *); int gfc_implicit_pure (gfc_symbol *);
void gfc_unset_implicit_pure (gfc_symbol *);
int gfc_elemental (gfc_symbol *); int gfc_elemental (gfc_symbol *);
bool gfc_resolve_iterator (gfc_iterator *, bool, bool); bool gfc_resolve_iterator (gfc_iterator *, bool, bool);
bool find_forall_index (gfc_expr *, gfc_symbol *, int); bool find_forall_index (gfc_expr *, gfc_symbol *, int);
......
...@@ -4404,13 +4404,16 @@ gfc_intrinsic_sub_interface (gfc_code *c, int error_flag) ...@@ -4404,13 +4404,16 @@ gfc_intrinsic_sub_interface (gfc_code *c, int error_flag)
return MATCH_ERROR; 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, gfc_error ("Subroutine call to intrinsic '%s' at %L is not PURE", name,
&c->loc); &c->loc);
return MATCH_ERROR; return MATCH_ERROR;
} }
if (!isym->pure)
gfc_unset_implicit_pure (NULL);
c->resolved_sym->attr.noreturn = isym->noreturn; c->resolved_sym->attr.noreturn = isym->noreturn;
return MATCH_YES; return MATCH_YES;
......
...@@ -1305,7 +1305,8 @@ match_vtag (const io_tag *tag, gfc_expr **v) ...@@ -1305,7 +1305,8 @@ match_vtag (const io_tag *tag, gfc_expr **v)
return MATCH_ERROR; 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", gfc_error ("Variable %s cannot be assigned in PURE procedure at %C",
tag->name); tag->name);
...@@ -1313,8 +1314,8 @@ match_vtag (const io_tag *tag, gfc_expr **v) ...@@ -1313,8 +1314,8 @@ match_vtag (const io_tag *tag, gfc_expr **v)
return MATCH_ERROR; return MATCH_ERROR;
} }
if (gfc_implicit_pure (NULL) && gfc_impure_variable (result->symtree->n.sym)) if (impure)
gfc_current_ns->proc_name->attr.implicit_pure = 0; gfc_unset_implicit_pure (NULL);
*v = result; *v = result;
return MATCH_YES; return MATCH_YES;
...@@ -1829,8 +1830,7 @@ gfc_match_open (void) ...@@ -1829,8 +1830,7 @@ gfc_match_open (void)
goto cleanup; goto cleanup;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
warn = (open->err || open->iostat) ? true : false; warn = (open->err || open->iostat) ? true : false;
...@@ -2242,8 +2242,7 @@ gfc_match_close (void) ...@@ -2242,8 +2242,7 @@ gfc_match_close (void)
goto cleanup; goto cleanup;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
warn = (close->iostat || close->err) ? true : false; warn = (close->iostat || close->err) ? true : false;
...@@ -2410,8 +2409,7 @@ done: ...@@ -2410,8 +2409,7 @@ done:
goto cleanup; goto cleanup;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
new_st.op = op; new_st.op = op;
new_st.ext.filepos = fp; new_st.ext.filepos = fp;
...@@ -3793,8 +3791,7 @@ gfc_match_print (void) ...@@ -3793,8 +3791,7 @@ gfc_match_print (void)
return MATCH_ERROR; return MATCH_ERROR;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
return MATCH_YES; return MATCH_YES;
} }
...@@ -3953,8 +3950,7 @@ gfc_match_inquire (void) ...@@ -3953,8 +3950,7 @@ gfc_match_inquire (void)
return MATCH_ERROR; return MATCH_ERROR;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
new_st.block = gfc_get_code (EXEC_IOLENGTH); new_st.block = gfc_get_code (EXEC_IOLENGTH);
terminate_io (code); terminate_io (code);
...@@ -4006,8 +4002,7 @@ gfc_match_inquire (void) ...@@ -4006,8 +4002,7 @@ gfc_match_inquire (void)
goto cleanup; goto cleanup;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
if (inquire->id != NULL && inquire->pending == NULL) if (inquire->id != NULL && inquire->pending == NULL)
{ {
...@@ -4195,8 +4190,7 @@ gfc_match_wait (void) ...@@ -4195,8 +4190,7 @@ gfc_match_wait (void)
goto cleanup; goto cleanup;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
new_st.op = EXEC_WAIT; new_st.op = EXEC_WAIT;
new_st.ext.wait = wait; new_st.ext.wait = wait;
......
...@@ -1751,8 +1751,7 @@ gfc_match_critical (void) ...@@ -1751,8 +1751,7 @@ gfc_match_critical (void)
return MATCH_ERROR; return MATCH_ERROR;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
if (!gfc_notify_std (GFC_STD_F2008, "CRITICAL statement at %C")) if (!gfc_notify_std (GFC_STD_F2008, "CRITICAL statement at %C"))
return MATCH_ERROR; return MATCH_ERROR;
...@@ -2676,8 +2675,7 @@ gfc_match_stopcode (gfc_statement st) ...@@ -2676,8 +2675,7 @@ gfc_match_stopcode (gfc_statement st)
goto cleanup; goto cleanup;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
if (st == ST_STOP && gfc_find_state (COMP_CRITICAL)) if (st == ST_STOP && gfc_find_state (COMP_CRITICAL))
{ {
...@@ -2814,8 +2812,7 @@ lock_unlock_statement (gfc_statement st) ...@@ -2814,8 +2812,7 @@ lock_unlock_statement (gfc_statement st)
return MATCH_ERROR; return MATCH_ERROR;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
if (gfc_option.coarray == GFC_FCOARRAY_NONE) if (gfc_option.coarray == GFC_FCOARRAY_NONE)
{ {
...@@ -3008,8 +3005,7 @@ sync_statement (gfc_statement st) ...@@ -3008,8 +3005,7 @@ sync_statement (gfc_statement st)
return MATCH_ERROR; return MATCH_ERROR;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
if (!gfc_notify_std (GFC_STD_F2008, "SYNC statement at %C")) if (!gfc_notify_std (GFC_STD_F2008, "SYNC statement at %C"))
return MATCH_ERROR; return MATCH_ERROR;
...@@ -3479,15 +3475,15 @@ gfc_match_allocate (void) ...@@ -3479,15 +3475,15 @@ gfc_match_allocate (void)
if (gfc_check_do_variable (tail->expr->symtree)) if (gfc_check_do_variable (tail->expr->symtree))
goto cleanup; 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"); gfc_error ("Bad allocate-object at %C for a PURE procedure");
goto cleanup; goto cleanup;
} }
if (gfc_implicit_pure (NULL) if (impure)
&& gfc_impure_variable (tail->expr->symtree->n.sym)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
if (tail->expr->ts.deferred) if (tail->expr->ts.deferred)
{ {
...@@ -3868,14 +3864,15 @@ gfc_match_deallocate (void) ...@@ -3868,14 +3864,15 @@ gfc_match_deallocate (void)
sym = tail->expr->symtree->n.sym; 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"); gfc_error ("Illegal allocate-object at %C for a PURE procedure");
goto cleanup; goto cleanup;
} }
if (gfc_implicit_pure (NULL) && gfc_impure_variable (sym)) if (impure)
gfc_current_ns->proc_name->attr.implicit_pure = 0; gfc_unset_implicit_pure (NULL);
if (gfc_is_coarray (tail->expr) if (gfc_is_coarray (tail->expr)
&& gfc_find_state (COMP_DO_CONCURRENT)) && gfc_find_state (COMP_DO_CONCURRENT))
......
...@@ -550,8 +550,7 @@ decode_omp_directive (void) ...@@ -550,8 +550,7 @@ decode_omp_directive (void)
return ST_NONE; return ST_NONE;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
old_locus = gfc_current_locus; old_locus = gfc_current_locus;
......
...@@ -1328,9 +1328,10 @@ resolve_structure_cons (gfc_expr *expr, int init) ...@@ -1328,9 +1328,10 @@ resolve_structure_cons (gfc_expr *expr, int init)
} }
/* F2003, C1272 (3). */ /* F2003, C1272 (3). */
if (gfc_pure (NULL) && cons->expr->expr_type == EXPR_VARIABLE bool impure = cons->expr->expr_type == EXPR_VARIABLE
&& (gfc_impure_variable (cons->expr->symtree->n.sym) && (gfc_impure_variable (cons->expr->symtree->n.sym)
|| gfc_is_coindexed (cons->expr))) || gfc_is_coindexed (cons->expr));
if (impure && gfc_pure (NULL))
{ {
t = false; t = false;
gfc_error ("Invalid expression in the structure constructor for " gfc_error ("Invalid expression in the structure constructor for "
...@@ -1338,12 +1339,8 @@ resolve_structure_cons (gfc_expr *expr, int init) ...@@ -1338,12 +1339,8 @@ resolve_structure_cons (gfc_expr *expr, int init)
comp->name, &cons->expr->where); comp->name, &cons->expr->where);
} }
if (gfc_implicit_pure (NULL) if (impure)
&& cons->expr->expr_type == EXPR_VARIABLE gfc_unset_implicit_pure (NULL);
&& (gfc_impure_variable (cons->expr->symtree->n.sym)
|| gfc_is_coindexed (cons->expr)))
gfc_current_ns->proc_name->attr.implicit_pure = 0;
} }
return t; return t;
...@@ -3006,8 +3003,7 @@ resolve_function (gfc_expr *expr) ...@@ -3006,8 +3003,7 @@ resolve_function (gfc_expr *expr)
t = false; t = false;
} }
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
} }
/* Functions without the RECURSIVE attribution are not allowed to /* Functions without the RECURSIVE attribution are not allowed to
...@@ -3072,8 +3068,7 @@ pure_subroutine (gfc_code *c, gfc_symbol *sym) ...@@ -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, gfc_error ("Subroutine call to '%s' at %L is not PURE", sym->name,
&c->loc); &c->loc);
if (gfc_implicit_pure (NULL)) gfc_unset_implicit_pure (NULL);
gfc_current_ns->proc_name->attr.implicit_pure = 0;
} }
...@@ -13927,6 +13922,33 @@ gfc_implicit_pure (gfc_symbol *sym) ...@@ -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. */ /* Test whether the current procedure is elemental or not. */
int int
......
...@@ -1114,8 +1114,8 @@ gfc_add_save (symbol_attribute *attr, save_state s, const char *name, ...@@ -1114,8 +1114,8 @@ gfc_add_save (symbol_attribute *attr, save_state s, const char *name,
return false; return false;
} }
if (s == SAVE_EXPLICIT && gfc_implicit_pure (NULL)) if (s == SAVE_EXPLICIT)
gfc_current_ns->proc_name->attr.implicit_pure = 0; gfc_unset_implicit_pure (NULL);
if (s == SAVE_EXPLICIT && attr->save == SAVE_EXPLICIT) if (s == SAVE_EXPLICIT && attr->save == SAVE_EXPLICIT)
{ {
......
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> 2014-03-19 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/51474 PR c++/51474
......
! { 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" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment