aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/resolve.c
diff options
context:
space:
mode:
authorTobias Burnus <burnus@gcc.gnu.org>2010-04-06 18:26:02 +0200
committerTobias Burnus <burnus@gcc.gnu.org>2010-04-06 18:26:02 +0200
commitd0a4a61c3de7ac131afc0014c6a8970ca6dcdeca (patch)
tree6b20ae56f767cd6edf0d68afa82cbb77738f5cfc /gcc/fortran/resolve.c
parent62daa13984dac4fbe37f94755978ad886925939d (diff)
downloadgcc-d0a4a61c3de7ac131afc0014c6a8970ca6dcdeca.zip
gcc-d0a4a61c3de7ac131afc0014c6a8970ca6dcdeca.tar.gz
gcc-d0a4a61c3de7ac131afc0014c6a8970ca6dcdeca.tar.bz2
re PR fortran/39997 (Procedure(), pointer & implicit typing: rejects-valid / accepts-invalid?)
2010-04-06 Tobias Burnus <burnus@net-b.de> PR fortran/39997 * intrinsic.c (add_functions): Add num_images. * decl.c (gfc_match_end): Handle END CRITICAL. * intrinsic.h (gfc_simplify_num_images): Add prototype. * dump-parse-tree.c (show_code_node): Dump CRITICAL, ERROR STOP, and SYNC. * gfortran.h (gfc_statement): Add enum items for those. (gfc_exec_op) Ditto. (gfc_isym_id): Add num_images. * trans-stmt.c (gfc_trans_stop): Handle ERROR STOP. (gfc_trans_sync,gfc_trans_critical): New functions. * trans-stmt.h (gfc_trans_stop,gfc_trans_sync, gfc_trans_critical): Add/update prototypes. * trans.c (gfc_trans_code): Handle CRITICAL, ERROR STOP, and SYNC statements. * trans.h (gfor_fndecl_error_stop_string) Add variable. * resolve.c (resolve_sync): Add function. (gfc_resolve_blocks): Handle CRITICAL. (resolve_code): Handle CRITICAL, ERROR STOP, (resolve_branch): Add CRITICAL constraint check. and SYNC statements. * st.c (gfc_free_statement): Add new statements. * trans-decl.c (gfor_fndecl_error_stop_string): Global variable. (gfc_build_builtin_function_decls): Initialize it. * match.c (gfc_match_if): Handle ERROR STOP and SYNC. (gfc_match_critical, gfc_match_error_stop, sync_statement, gfc_match_sync_all, gfc_match_sync_images, gfc_match_sync_memory): New functions. (match_exit_cycle): Handle CRITICAL constraint. (gfc_match_stopcode): Handle ERROR STOP. * match.h (gfc_match_critical, gfc_match_error_stop, gfc_match_sync_all, gfc_match_sync_images, gfc_match_sync_memory): Add prototype. * parse.c (decode_statement, gfc_ascii_statement, parse_executable): Handle new statements. (parse_critical_block): New function. * parse.h (gfc_compile_state): Add COMP_CRITICAL. * intrinsic.texi (num_images): Document new function. * simplify.c (gfc_simplify_num_images): Add function. 2010-04-06 Tobias Burnus <burnus@net-b.de> PR fortran/39997 * gfortran.dg/coarray_1.f90: New test. * gfortran.dg/coarray_2.f90: New test. * gfortran.dg/coarray_3.f90: New test. 2010-04-06 Tobias Burnus <burnus@net-b.de> PR fortran/39997 * runtime/stop.c (error_stop_string): New function. * gfortran.map (_gfortran_error_stop_string): Add. From-SVN: r158008
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r--gcc/fortran/resolve.c78
1 files changed, 75 insertions, 3 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 24ec7a8..8ef347d 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -7315,6 +7315,48 @@ find_reachable_labels (gfc_code *block)
}
}
+
+static void
+resolve_sync (gfc_code *code)
+{
+ /* Check imageset. The * case matches expr1 == NULL. */
+ if (code->expr1)
+ {
+ if (code->expr1->ts.type != BT_INTEGER || code->expr1->rank > 1)
+ gfc_error ("Imageset argument at %L must be a scalar or rank-1 "
+ "INTEGER expression", &code->expr1->where);
+ if (code->expr1->expr_type == EXPR_CONSTANT && code->expr1->rank == 0
+ && mpz_cmp_si (code->expr1->value.integer, 1) < 0)
+ gfc_error ("Imageset argument at %L must between 1 and num_images()",
+ &code->expr1->where);
+ else if (code->expr1->expr_type == EXPR_ARRAY
+ && gfc_simplify_expr (code->expr1, 0) == SUCCESS)
+ {
+ gfc_constructor *cons;
+ for (cons = code->expr1->value.constructor; cons; cons = cons->next)
+ if (cons->expr->expr_type == EXPR_CONSTANT
+ && mpz_cmp_si (cons->expr->value.integer, 1) < 0)
+ gfc_error ("Imageset argument at %L must between 1 and "
+ "num_images()", &cons->expr->where);
+ }
+ }
+
+ /* Check STAT. */
+ if (code->expr2
+ && (code->expr2->ts.type != BT_INTEGER || code->expr2->rank != 0
+ || code->expr2->expr_type != EXPR_VARIABLE))
+ gfc_error ("STAT= argument at %L must be a scalar INTEGER variable",
+ &code->expr2->where);
+
+ /* Check ERRMSG. */
+ if (code->expr3
+ && (code->expr3->ts.type != BT_CHARACTER || code->expr3->rank != 0
+ || code->expr3->expr_type != EXPR_VARIABLE))
+ gfc_error ("ERRMSG= argument at %L must be a scalar CHARACTER variable",
+ &code->expr3->where);
+}
+
+
/* Given a branch to a label, see if the branch is conforming.
The code node describes where the branch is located. */
@@ -7355,15 +7397,36 @@ resolve_branch (gfc_st_label *label, gfc_code *code)
the bitmap reachable_labels. */
if (bitmap_bit_p (cs_base->reachable_labels, label->value))
- return;
+ {
+ /* Check now whether there is a CRITICAL construct; if so, check
+ whether the label is still visible outside of the CRITICAL block,
+ which is invalid. */
+ for (stack = cs_base; stack; stack = stack->prev)
+ if (stack->current->op == EXEC_CRITICAL
+ && bitmap_bit_p (stack->reachable_labels, label->value))
+ gfc_error ("GOTO statement at %L leaves CRITICAL construct for label"
+ " at %L", &code->loc, &label->where);
+
+ return;
+ }
/* Step four: If we haven't found the label in the bitmap, it may
still be the label of the END of the enclosing block, in which
case we find it by going up the code_stack. */
for (stack = cs_base; stack; stack = stack->prev)
- if (stack->current->next && stack->current->next->here == label)
- break;
+ {
+ if (stack->current->next && stack->current->next->here == label)
+ break;
+ if (stack->current->op == EXEC_CRITICAL)
+ {
+ /* Note: A label at END CRITICAL does not leave the CRITICAL
+ construct as END CRITICAL is still part of it. */
+ gfc_error ("GOTO statement at %L leaves CRITICAL construct for label"
+ " at %L", &code->loc, &label->where);
+ return;
+ }
+ }
if (stack)
{
@@ -7788,6 +7851,7 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
case EXEC_FORALL:
case EXEC_DO:
case EXEC_DO_WHILE:
+ case EXEC_CRITICAL:
case EXEC_READ:
case EXEC_WRITE:
case EXEC_IOLENGTH:
@@ -8068,10 +8132,18 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
case EXEC_CYCLE:
case EXEC_PAUSE:
case EXEC_STOP:
+ case EXEC_ERROR_STOP:
case EXEC_EXIT:
case EXEC_CONTINUE:
case EXEC_DT_END:
case EXEC_ASSIGN_CALL:
+ case EXEC_CRITICAL:
+ break;
+
+ case EXEC_SYNC_ALL:
+ case EXEC_SYNC_IMAGES:
+ case EXEC_SYNC_MEMORY:
+ resolve_sync (code);
break;
case EXEC_ENTRY: