diff options
author | Tobias Burnus <burnus@gcc.gnu.org> | 2010-04-06 18:26:02 +0200 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2010-04-06 18:26:02 +0200 |
commit | d0a4a61c3de7ac131afc0014c6a8970ca6dcdeca (patch) | |
tree | 6b20ae56f767cd6edf0d68afa82cbb77738f5cfc /gcc/fortran/resolve.c | |
parent | 62daa13984dac4fbe37f94755978ad886925939d (diff) | |
download | gcc-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.c | 78 |
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: |