aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/parse.c
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2019-09-01 12:53:02 +0000
committerPaul Thomas <pault@gcc.gnu.org>2019-09-01 12:53:02 +0000
commit70570ec1927450952efc5baa4de3254507352f09 (patch)
treed0baf00593ad714a097942a7238267ec362f1411 /gcc/fortran/parse.c
parent3e7254c5e4a0545059ca61b34134f7ef5c3d3a86 (diff)
downloadgcc-70570ec1927450952efc5baa4de3254507352f09.zip
gcc-70570ec1927450952efc5baa4de3254507352f09.tar.gz
gcc-70570ec1927450952efc5baa4de3254507352f09.tar.bz2
array.c (spec_dimen_size): Check for the presence of expressions for the bounds.
2019-09-01 Paul Thomas <pault@gcc.gnu.org> * array.c (spec_dimen_size): Check for the presence of expressions for the bounds. * decl.c (gfc_match_end): Add case COMP_SELECT_RANK. * dump-parse-tree.c(show_symbol): Show the arrayspec of class entities. (show_code_node): Show the code for SELECT_RANK. * expr.c (gfc_check_vardef_context): Omit the context of variable definition for select rank associate names since the ASSUMED RANK throws. * gfortran.h : Add ST_SELECT_RANK and ST_RANK to enum gfc_statement. Add select_rank_temporary to symbol attribute structure. Add EXEC_SELECT_RANK to enum gfc_exec_op. * match.c (match_exit_cycle): Add COMP_SELECT_RANK. (copy_ts_from_selector_to_associate): Add as special case for assumed rank class variables. (select_intrinsic_set_tmp): Clean up the code by using symbols for references to the temporary and the selector. (select_type_set_tmp): Ditto. (select_rank_set_tmp): New function. (gfc_match_select_rank): New function. (gfc_match_rank_is): New function. * match.h : Add prototypes for gfc_match_select_rank and gfc_match_rank_is. * parse.c (decode_statement): Attempt to match select_rank and rank statements. (next_statement, gfc_ascii_statement): Add ST_SELECT_RANK. (parse_select_rank_block): New function. (parse_executable): Parse select rank block for ST_SELECT_RANK. * parse.h : Add COMP_SELECT_RANK to enum gfc_compile_state. * resolve.c (resolve_variable): Exclude select_rank_temporaries from the check on use of ASSUMED RANK. (gfc_resolve_expr): Make sure that unlimited polymorphic select rank temporaries expressions are not resolved again after being successfully resolved. (resolve_assoc_var): Do not do the rank check for select rank temporaries. (resolve_select_rank): New function. (gfc_resolve_blocks): Deal with case EXEC_SELECT_RANK. (resolve_symbol): Exclude select rank temporaries for check on use of ASSUMED RANK. * st.c (gfc_free_statement): Include EXEC_SELECT_RANK. * trans-array.c (gfc_conv_array_ref): Select rank temporaries may have dimen == 0. (gfc_conv_expr_descriptor): Zero the offset of select rank temporaries. * trans-stmt.c (copy_descriptor): New function. (trans_associate_var): Add code to associate select rank temps. (gfc_trans_select_rank_cases): New function. (gfc_trans_select_rank): New function. * trans-stmt.h : Add prototype for gfc_trans_select_rank. trans.c (trans_code): Add select rank case. 2019-09-01 Paul Thomas <pault@gcc.gnu.org> * gfortran.dg/select_rank_1.f90 : New test. * gfortran.dg/select_rank_2.f90 : New test. From-SVN: r275269
Diffstat (limited to 'gcc/fortran/parse.c')
-rw-r--r--gcc/fortran/parse.c95
1 files changed, 91 insertions, 4 deletions
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 8950b6a..caea16b 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -426,6 +426,7 @@ decode_statement (void)
match (NULL, gfc_match_critical, ST_CRITICAL);
match (NULL, gfc_match_select, ST_SELECT_CASE);
match (NULL, gfc_match_select_type, ST_SELECT_TYPE);
+ match (NULL, gfc_match_select_rank, ST_SELECT_RANK);
/* General statement matching: Instead of testing every possible
statement, we eliminate most possibilities by peeking at the
@@ -546,6 +547,7 @@ decode_statement (void)
break;
case 'r':
+ match ("rank", gfc_match_rank_is, ST_RANK);
match ("read", gfc_match_read, ST_READ);
match ("return", gfc_match_return, ST_RETURN);
match ("rewind", gfc_match_rewind, ST_REWIND);
@@ -1537,7 +1539,7 @@ next_statement (void)
#define case_exec_markers case ST_DO: case ST_FORALL_BLOCK: \
case ST_IF_BLOCK: case ST_BLOCK: case ST_ASSOCIATE: \
case ST_WHERE_BLOCK: case ST_SELECT_CASE: case ST_SELECT_TYPE: \
- case ST_OMP_PARALLEL: \
+ case ST_SELECT_RANK: case ST_OMP_PARALLEL: \
case ST_OMP_PARALLEL_SECTIONS: case ST_OMP_SECTIONS: case ST_OMP_ORDERED: \
case ST_OMP_CRITICAL: case ST_OMP_MASTER: case ST_OMP_SINGLE: \
case ST_OMP_DO: case ST_OMP_PARALLEL_DO: case ST_OMP_ATOMIC: \
@@ -2077,12 +2079,18 @@ gfc_ascii_statement (gfc_statement st)
case ST_SELECT_TYPE:
p = "SELECT TYPE";
break;
+ case ST_SELECT_RANK:
+ p = "SELECT RANK";
+ break;
case ST_TYPE_IS:
p = "TYPE IS";
break;
case ST_CLASS_IS:
p = "CLASS IS";
break;
+ case ST_RANK:
+ p = "RANK";
+ break;
case ST_SEQUENCE:
p = "SEQUENCE";
break;
@@ -4179,7 +4187,7 @@ parse_select_block (void)
reject_statement ();
}
- /* At this point, we're got a nonempty select block. */
+ /* At this point, we've got a nonempty select block. */
cp = new_level (cp);
*cp = new_st;
@@ -4263,7 +4271,7 @@ parse_select_type_block (void)
reject_statement ();
}
- /* At this point, we're got a nonempty select block. */
+ /* At this point, we've got a nonempty select block. */
cp = new_level (cp);
*cp = new_st;
@@ -4306,6 +4314,81 @@ done:
}
+/* Parse a SELECT RANK construct. */
+
+static void
+parse_select_rank_block (void)
+{
+ gfc_statement st;
+ gfc_code *cp;
+ gfc_state_data s;
+
+ gfc_current_ns = new_st.ext.block.ns;
+ accept_statement (ST_SELECT_RANK);
+
+ cp = gfc_state_stack->tail;
+ push_state (&s, COMP_SELECT_RANK, gfc_new_block);
+
+ /* Make sure that the next statement is a RANK IS or RANK DEFAULT. */
+ for (;;)
+ {
+ st = next_statement ();
+ if (st == ST_NONE)
+ unexpected_eof ();
+ if (st == ST_END_SELECT)
+ /* Empty SELECT CASE is OK. */
+ goto done;
+ if (st == ST_RANK)
+ break;
+
+ gfc_error ("Expected RANK or RANK DEFAULT "
+ "following SELECT RANK at %C");
+
+ reject_statement ();
+ }
+
+ /* At this point, we've got a nonempty select block. */
+ cp = new_level (cp);
+ *cp = new_st;
+
+ accept_statement (st);
+
+ do
+ {
+ st = parse_executable (ST_NONE);
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_RANK:
+ cp = new_level (gfc_state_stack->head);
+ *cp = new_st;
+ gfc_clear_new_st ();
+
+ accept_statement (st);
+ /* Fall through */
+
+ case ST_END_SELECT:
+ break;
+
+ /* Can't have an executable statement because of
+ parse_executable(). */
+ default:
+ unexpected_statement (st);
+ break;
+ }
+ }
+ while (st != ST_END_SELECT);
+
+done:
+ pop_state ();
+ accept_statement (st);
+ gfc_current_ns = gfc_current_ns->parent;
+ select_type_pop ();
+}
+
+
/* Given a symbol, make sure it is not an iteration variable for a DO
statement. This subroutine is called when the symbol is seen in a
context that causes it to become redefined. If the symbol is an
@@ -5360,6 +5443,10 @@ parse_executable (gfc_statement st)
parse_select_type_block ();
break;
+ case ST_SELECT_RANK:
+ parse_select_rank_block ();
+ break;
+
case ST_DO:
parse_do_block ();
if (check_do_closure () == 1)
@@ -6410,7 +6497,7 @@ done:
if (flag_dump_fortran_global)
gfc_dump_global_symbols (stdout);
-
+
gfc_end_source_files ();
return true;