aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/check.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/check.cc')
-rw-r--r--gcc/fortran/check.cc617
1 files changed, 409 insertions, 208 deletions
diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 3545864..838d523 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -67,7 +67,7 @@ gfc_invalid_boz (const char *msg, locus *loc)
return false;
}
- const char *hint = _(" [see %<-fno-allow-invalid-boz%>]");
+ const char *hint = _(" [see %<-fallow-invalid-boz%>]");
size_t len = strlen (msg) + strlen (hint) + 1;
char *msg2 = (char *) alloca (len);
strcpy (msg2, msg);
@@ -1809,6 +1809,23 @@ gfc_check_atomic_ref (gfc_expr *value, gfc_expr *atom, gfc_expr *stat)
return gfc_check_atomic (atom, 1, value, 0, stat, 2);
}
+bool
+team_type_check (gfc_expr *e, int n)
+{
+ if (e->ts.type != BT_DERIVED || !e->ts.u.derived
+ || e->ts.u.derived->from_intmod != INTMOD_ISO_FORTRAN_ENV
+ || e->ts.u.derived->intmod_sym_id != ISOFORTRAN_TEAM_TYPE)
+ {
+ gfc_error ("%qs argument of %qs intrinsic at %L shall be of type "
+ "%<team_type%> from the intrinsic module "
+ "%<ISO_FORTRAN_ENV%>",
+ gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
+ &e->where);
+ return false;
+ }
+
+ return true;
+}
bool
gfc_check_image_status (gfc_expr *image, gfc_expr *team)
@@ -1818,14 +1835,7 @@ gfc_check_image_status (gfc_expr *image, gfc_expr *team)
|| !positive_check (0, image))
return false;
- if (team)
- {
- gfc_error ("%qs argument of %qs intrinsic at %L not yet supported",
- gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
- &team->where);
- return false;
- }
- return true;
+ return !team || (scalar_check (team, 0) && team_type_check (team, 0));
}
@@ -1905,10 +1915,25 @@ gfc_check_get_team (gfc_expr *level)
{
if (level)
{
- gfc_error ("%qs argument of %qs intrinsic at %L not yet supported",
- gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
- &level->where);
- return false;
+ int l;
+
+ if (!type_check (level, 0, BT_INTEGER) || !scalar_check (level, 0))
+ return false;
+
+ /* When level is a constant, try to extract it. If not, the runtime has
+ to check. */
+ if (gfc_extract_int (level, &l, 0))
+ return true;
+
+ if (l < GFC_CAF_INITIAL_TEAM || l > GFC_CAF_CURRENT_TEAM)
+ {
+ gfc_error ("%qs argument of %qs intrinsic at %L shall specify one of "
+ "the INITIAL_TEAM, PARENT_TEAM or CURRENT_TEAM constants "
+ "from the intrinsic module ISO_FORTRAN_ENV",
+ gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
+ &level->where);
+ return false;
+ }
}
return true;
}
@@ -2442,31 +2467,24 @@ gfc_check_co_broadcast (gfc_expr *a, gfc_expr *source_image, gfc_expr *stat,
}
-bool
-gfc_check_co_reduce (gfc_expr *a, gfc_expr *op, gfc_expr *result_image,
- gfc_expr *stat, gfc_expr *errmsg)
+/* Helper function for character arguments in gfc_check_[co_]reduce. */
+
+static unsigned long
+get_ul_from_cst_cl (const gfc_charlen *cl)
+{
+ return cl && cl->length && cl->length->expr_type == EXPR_CONSTANT
+ ? mpz_get_ui (cl->length->value.integer) : 0;
+};
+
+
+/* Checks shared between co_reduce and reduce. */
+static bool
+check_operation (gfc_expr *op, gfc_expr *a, bool is_co_reduce)
{
symbol_attribute attr;
gfc_formal_arglist *formal;
gfc_symbol *sym;
- if (a->ts.type == BT_CLASS)
- {
- gfc_error ("The A argument at %L of CO_REDUCE shall not be polymorphic",
- &a->where);
- return false;
- }
-
- if (gfc_expr_attr (a).alloc_comp)
- {
- gfc_error ("Support for the A argument at %L with allocatable components"
- " is not yet implemented", &a->where);
- return false;
- }
-
- if (!check_co_collective (a, result_image, stat, errmsg, true))
- return false;
-
if (!gfc_resolve_expr (op))
return false;
@@ -2483,8 +2501,9 @@ gfc_check_co_reduce (gfc_expr *a, gfc_expr *op, gfc_expr *result_image,
/* None of the intrinsics fulfills the criteria of taking two arguments,
returning the same type and kind as the arguments and being permitted
as actual argument. */
- gfc_error ("Intrinsic function %s at %L is not permitted for CO_REDUCE",
- op->symtree->n.sym->name, &op->where);
+ gfc_error ("Intrinsic function %s at %L is not permitted for %s",
+ op->symtree->n.sym->name, &op->where,
+ is_co_reduce ? "CO_REDUCE" : "REDUCE");
return false;
}
@@ -2510,12 +2529,14 @@ gfc_check_co_reduce (gfc_expr *a, gfc_expr *op, gfc_expr *result_image,
if (!gfc_compare_types (&a->ts, &sym->result->ts))
{
- gfc_error ("The A argument at %L has type %s but the function passed as "
- "OPERATION at %L returns %s",
+ gfc_error ("The %s argument at %L has type %s but the function passed "
+ "as OPERATION at %L returns %s",
+ is_co_reduce ? "A" : "ARRAY",
&a->where, gfc_typename (a), &op->where,
gfc_typename (&sym->result->ts));
return false;
}
+
if (!gfc_compare_types (&a->ts, &formal->sym->ts)
|| !gfc_compare_types (&a->ts, &formal->next->sym->ts))
{
@@ -2567,42 +2588,59 @@ gfc_check_co_reduce (gfc_expr *a, gfc_expr *op, gfc_expr *result_image,
if (a->ts.type == BT_CHARACTER)
{
- gfc_charlen *cl;
unsigned long actual_size, formal_size1, formal_size2, result_size;
- cl = a->ts.u.cl;
- actual_size = cl && cl->length && cl->length->expr_type == EXPR_CONSTANT
- ? mpz_get_ui (cl->length->value.integer) : 0;
-
- cl = formal->sym->ts.u.cl;
- formal_size1 = cl && cl->length && cl->length->expr_type == EXPR_CONSTANT
- ? mpz_get_ui (cl->length->value.integer) : 0;
-
- cl = formal->next->sym->ts.u.cl;
- formal_size2 = cl && cl->length && cl->length->expr_type == EXPR_CONSTANT
- ? mpz_get_ui (cl->length->value.integer) : 0;
-
- cl = sym->ts.u.cl;
- result_size = cl && cl->length && cl->length->expr_type == EXPR_CONSTANT
- ? mpz_get_ui (cl->length->value.integer) : 0;
+ actual_size = get_ul_from_cst_cl (a->ts.u.cl);
+ formal_size1 = get_ul_from_cst_cl (formal->sym->ts.u.cl);
+ formal_size2 = get_ul_from_cst_cl (formal->next->sym->ts.u.cl);
+ result_size = get_ul_from_cst_cl (sym->ts.u.cl);
if (actual_size
&& ((formal_size1 && actual_size != formal_size1)
|| (formal_size2 && actual_size != formal_size2)))
{
- gfc_error ("The character length of the A argument at %L and of the "
- "arguments of the OPERATION at %L shall be the same",
- &a->where, &op->where);
+ gfc_error ("The character length of the %s argument at %L and of "
+ "the arguments of the OPERATION at %L shall be the same",
+ is_co_reduce ? "A" : "ARRAY", &a->where, &op->where);
return false;
}
+
if (actual_size && result_size && actual_size != result_size)
{
- gfc_error ("The character length of the A argument at %L and of the "
- "function result of the OPERATION at %L shall be the same",
+ gfc_error ("The character length of the %s argument at %L and of "
+ "the function result of the OPERATION at %L shall be the "
+ "same", is_co_reduce ? "A" : "ARRAY",
&a->where, &op->where);
return false;
}
}
+ return true;
+}
+
+
+bool
+gfc_check_co_reduce (gfc_expr *a, gfc_expr *op, gfc_expr *result_image,
+ gfc_expr *stat, gfc_expr *errmsg)
+{
+ if (a->ts.type == BT_CLASS)
+ {
+ gfc_error ("The A argument at %L of CO_REDUCE shall not be polymorphic",
+ &a->where);
+ return false;
+ }
+
+ if (gfc_expr_attr (a).alloc_comp)
+ {
+ gfc_error ("Support for the A argument at %L with allocatable components"
+ " is not yet implemented", &a->where);
+ return false;
+ }
+
+ if (!check_co_collective (a, result_image, stat, errmsg, true))
+ return false;
+
+ if (!check_operation (op, a, true))
+ return false;
return true;
}
@@ -3797,7 +3835,8 @@ gfc_check_lcobound (gfc_expr *coarray, gfc_expr *dim, gfc_expr *kind)
{
if (flag_coarray == GFC_FCOARRAY_NONE)
{
- gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
+ gfc_fatal_error ("Coarrays disabled at %L, use %<-fcoarray=%> to enable",
+ gfc_current_intrinsic_where);
return false;
}
@@ -4670,8 +4709,18 @@ gfc_check_merge_bits (gfc_expr *i, gfc_expr *j, gfc_expr *mask)
bool
-gfc_check_move_alloc (gfc_expr *from, gfc_expr *to)
+gfc_check_move_alloc (gfc_expr *from, gfc_expr *to, gfc_expr *stat,
+ gfc_expr *errmsg)
{
+ struct sync_stat sync_stat = {stat, errmsg};
+
+ if ((stat || errmsg)
+ && !gfc_notify_std (GFC_STD_F2008, "STAT= or ERRMSG= at %L not supported",
+ &to->where))
+ return false;
+
+ gfc_resolve_sync_stat (&sync_stat);
+
if (!variable_check (from, 0, false))
return false;
if (!allocatable_check (from, 0))
@@ -5136,6 +5185,62 @@ gfc_check_real (gfc_expr *a, gfc_expr *kind)
bool
+gfc_check_reduce (gfc_expr *array, gfc_expr *operation, gfc_expr *dim,
+ gfc_expr *mask, gfc_expr *identity, gfc_expr *ordered)
+{
+ if (array->ts.type == BT_CLASS)
+ {
+ gfc_error ("The ARRAY argument at %L of REDUCE shall not be polymorphic",
+ &array->where);
+ return false;
+ }
+
+ if (!check_operation (operation, array, false))
+ return false;
+
+ if (dim && (dim->rank || dim->ts.type != BT_INTEGER))
+ {
+ gfc_error ("The DIM argument at %L, if present, must be an integer "
+ "scalar", &dim->where);
+ return false;
+ }
+
+ if (mask && (array->rank != mask->rank || mask->ts.type != BT_LOGICAL))
+ {
+ gfc_error ("The MASK argument at %L, if present, must be a logical "
+ "array with the same rank as ARRAY", &mask->where);
+ return false;
+ }
+
+ if (mask
+ && !gfc_check_conformance (array, mask,
+ _("arguments '%s' and '%s' for intrinsic %s"),
+ "ARRAY", "MASK", "REDUCE"))
+ return false;
+
+ if (mask && !identity)
+ gfc_warning (0, "MASK present at %L without IDENTITY", &mask->where);
+
+ if (ordered && (ordered->rank || ordered->ts.type != BT_LOGICAL))
+ {
+ gfc_error ("The ORDERED argument at %L, if present, must be a logical "
+ "scalar", &ordered->where);
+ return false;
+ }
+
+ if (identity && (identity->rank
+ || !gfc_compare_types (&array->ts, &identity->ts)))
+ {
+ gfc_error ("The IDENTITY argument at %L, if present, must be a scalar "
+ "with the same type as ARRAY", &identity->where);
+ return false;
+ }
+
+ return true;
+}
+
+
+bool
gfc_check_rename (gfc_expr *path1, gfc_expr *path2)
{
if (!type_check (path1, 0, BT_CHARACTER))
@@ -5847,39 +5952,110 @@ gfc_check_c_sizeof (gfc_expr *arg)
}
-bool
-gfc_check_c_associated (gfc_expr *c_ptr_1, gfc_expr *c_ptr_2)
+/* Helper functions check_c_ptr_1 and check_c_ptr_2
+ used in gfc_check_c_associated. */
+
+static inline
+bool check_c_ptr_1 (gfc_expr *c_ptr_1)
{
+ if ((c_ptr_1->ts.type == BT_VOID)
+ && (c_ptr_1->expr_type == EXPR_FUNCTION))
+ return true;
+
if (c_ptr_1->ts.type != BT_DERIVED
|| c_ptr_1->ts.u.derived->from_intmod != INTMOD_ISO_C_BINDING
|| (c_ptr_1->ts.u.derived->intmod_sym_id != ISOCBINDING_PTR
&& c_ptr_1->ts.u.derived->intmod_sym_id != ISOCBINDING_FUNPTR))
- {
- gfc_error ("Argument C_PTR_1 at %L to C_ASSOCIATED shall have the "
- "type TYPE(C_PTR) or TYPE(C_FUNPTR)", &c_ptr_1->where);
- return false;
- }
+ goto check_1_error;
+
+ if ((c_ptr_1->ts.type == BT_DERIVED)
+ && (c_ptr_1->expr_type == EXPR_STRUCTURE)
+ && (c_ptr_1->ts.u.derived->intmod_sym_id
+ == ISOCBINDING_NULL_FUNPTR))
+ goto check_1_error;
- if (!scalar_check (c_ptr_1, 0))
+ if (scalar_check (c_ptr_1, 0))
+ return true;
+ else
+ /* Return since the check_1_error message may not apply here. */
return false;
- if (c_ptr_2
- && (c_ptr_2->ts.type != BT_DERIVED
- || c_ptr_2->ts.u.derived->from_intmod != INTMOD_ISO_C_BINDING
- || (c_ptr_1->ts.u.derived->intmod_sym_id
- != c_ptr_2->ts.u.derived->intmod_sym_id)))
- {
- gfc_error ("Argument C_PTR_2 at %L to C_ASSOCIATED shall have the "
- "same type as C_PTR_1: %s instead of %s", &c_ptr_1->where,
- gfc_typename (&c_ptr_1->ts),
- gfc_typename (&c_ptr_2->ts));
- return false;
- }
+check_1_error:
+
+ gfc_error ("Argument C_PTR_1 at %L to C_ASSOCIATED shall have the "
+ "type TYPE(C_PTR) or TYPE(C_FUNPTR)", &c_ptr_1->where);
+ return false;
+}
- if (c_ptr_2 && !scalar_check (c_ptr_2, 1))
+static inline
+bool check_c_ptr_2 (gfc_expr *c_ptr_1, gfc_expr *c_ptr_2)
+{
+ switch (c_ptr_2->ts.type)
+ {
+ case BT_VOID:
+ if (c_ptr_2->expr_type == EXPR_FUNCTION)
+ {
+ if ((c_ptr_1->ts.type == BT_DERIVED)
+ && c_ptr_1->expr_type == EXPR_STRUCTURE
+ && (c_ptr_1->ts.u.derived->intmod_sym_id
+ == ISOCBINDING_FUNPTR))
+ goto check_2_error;
+ }
+ break;
+
+ case BT_DERIVED:
+ if ((c_ptr_2->expr_type == EXPR_STRUCTURE)
+ && (c_ptr_2->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR)
+ && (c_ptr_1->ts.type == BT_VOID)
+ && (c_ptr_1->expr_type == EXPR_FUNCTION))
+ return scalar_check (c_ptr_2, 1);
+
+ if ((c_ptr_2->expr_type == EXPR_STRUCTURE)
+ && (c_ptr_1->ts.type == BT_VOID)
+ && (c_ptr_1->expr_type == EXPR_FUNCTION))
+ goto check_2_error;
+
+ if (c_ptr_2->ts.u.derived->from_intmod != INTMOD_ISO_C_BINDING)
+ goto check_2_error;
+
+ if (c_ptr_1->ts.type == BT_DERIVED
+ && (c_ptr_1->ts.u.derived->intmod_sym_id
+ != c_ptr_2->ts.u.derived->intmod_sym_id))
+ goto check_2_error;
+ break;
+
+ default:
+ goto check_2_error;
+ }
+
+ if (scalar_check (c_ptr_2, 1))
+ return true;
+ else
+ /* Return since the check_2_error message may not apply here. */
return false;
- return true;
+check_2_error:
+
+ gfc_error ("Argument C_PTR_2 at %L to C_ASSOCIATED shall have the "
+ "same type as C_PTR_1, found %s instead of %s", &c_ptr_2->where,
+ gfc_typename (&c_ptr_2->ts), gfc_typename (&c_ptr_1->ts));
+
+ return false;
+ }
+
+
+bool
+gfc_check_c_associated (gfc_expr *c_ptr_1, gfc_expr *c_ptr_2)
+{
+ if (c_ptr_2)
+ {
+ if (check_c_ptr_2 (c_ptr_1, c_ptr_2))
+ return check_c_ptr_1 (c_ptr_1);
+ else
+ return false;
+ }
+ else
+ return check_c_ptr_1 (c_ptr_1);
}
@@ -6331,7 +6507,7 @@ gfc_check_fseek_sub (gfc_expr *unit, gfc_expr *offset, gfc_expr *whence, gfc_exp
bool
-gfc_check_fstat (gfc_expr *unit, gfc_expr *array)
+gfc_check_fstat (gfc_expr *unit, gfc_expr *values)
{
if (!type_check (unit, 0, BT_INTEGER))
return false;
@@ -6339,11 +6515,17 @@ gfc_check_fstat (gfc_expr *unit, gfc_expr *array)
if (!scalar_check (unit, 0))
return false;
- if (!type_check (array, 1, BT_INTEGER)
+ if (!type_check (values, 1, BT_INTEGER)
|| !kind_value_check (unit, 0, gfc_default_integer_kind))
return false;
- if (!array_check (array, 1))
+ if (!array_check (values, 1))
+ return false;
+
+ if (!variable_check (values, 1, false))
+ return false;
+
+ if (!array_size_check (values, 1, 13))
return false;
return true;
@@ -6351,19 +6533,9 @@ gfc_check_fstat (gfc_expr *unit, gfc_expr *array)
bool
-gfc_check_fstat_sub (gfc_expr *unit, gfc_expr *array, gfc_expr *status)
+gfc_check_fstat_sub (gfc_expr *unit, gfc_expr *values, gfc_expr *status)
{
- if (!type_check (unit, 0, BT_INTEGER))
- return false;
-
- if (!scalar_check (unit, 0))
- return false;
-
- if (!type_check (array, 1, BT_INTEGER)
- || !kind_value_check (array, 1, gfc_default_integer_kind))
- return false;
-
- if (!array_check (array, 1))
+ if (!gfc_check_fstat (unit, values))
return false;
if (status == NULL)
@@ -6376,6 +6548,9 @@ gfc_check_fstat_sub (gfc_expr *unit, gfc_expr *array, gfc_expr *status)
if (!scalar_check (status, 2))
return false;
+ if (!variable_check (status, 2, false))
+ return false;
+
return true;
}
@@ -6413,18 +6588,24 @@ gfc_check_ftell_sub (gfc_expr *unit, gfc_expr *offset)
bool
-gfc_check_stat (gfc_expr *name, gfc_expr *array)
+gfc_check_stat (gfc_expr *name, gfc_expr *values)
{
if (!type_check (name, 0, BT_CHARACTER))
return false;
if (!kind_value_check (name, 0, gfc_default_character_kind))
return false;
- if (!type_check (array, 1, BT_INTEGER)
- || !kind_value_check (array, 1, gfc_default_integer_kind))
+ if (!type_check (values, 1, BT_INTEGER)
+ || !kind_value_check (values, 1, gfc_default_integer_kind))
+ return false;
+
+ if (!array_check (values, 1))
+ return false;
+
+ if (!variable_check (values, 1, false))
return false;
- if (!array_check (array, 1))
+ if (!array_size_check (values, 1, 13))
return false;
return true;
@@ -6432,42 +6613,38 @@ gfc_check_stat (gfc_expr *name, gfc_expr *array)
bool
-gfc_check_stat_sub (gfc_expr *name, gfc_expr *array, gfc_expr *status)
+gfc_check_stat_sub (gfc_expr *name, gfc_expr *values, gfc_expr *status)
{
- if (!type_check (name, 0, BT_CHARACTER))
- return false;
- if (!kind_value_check (name, 0, gfc_default_character_kind))
- return false;
-
- if (!type_check (array, 1, BT_INTEGER)
- || !kind_value_check (array, 1, gfc_default_integer_kind))
- return false;
-
- if (!array_check (array, 1))
+ if (!gfc_check_stat (name, values))
return false;
if (status == NULL)
return true;
if (!type_check (status, 2, BT_INTEGER)
- || !kind_value_check (array, 1, gfc_default_integer_kind))
+ || !kind_value_check (status, 2, gfc_default_integer_kind))
return false;
if (!scalar_check (status, 2))
return false;
+ if (!variable_check (status, 2, false))
+ return false;
+
return true;
}
bool
-gfc_check_image_index (gfc_expr *coarray, gfc_expr *sub)
+gfc_check_image_index (gfc_expr *coarray, gfc_expr *sub,
+ gfc_expr *team_or_team_number)
{
mpz_t nelems;
if (flag_coarray == GFC_FCOARRAY_NONE)
{
- gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
+ gfc_fatal_error ("Coarrays disabled at %L, use %<-fcoarray=%> to enable",
+ gfc_current_intrinsic_where);
return false;
}
@@ -6481,12 +6658,8 @@ gfc_check_image_index (gfc_expr *coarray, gfc_expr *sub)
return false;
}
- if (sub->ts.type != BT_INTEGER)
- {
- gfc_error ("Type of %s argument of IMAGE_INDEX at %L shall be INTEGER",
- gfc_current_intrinsic_arg[1]->name, &sub->where);
- return false;
- }
+ if (!type_check (sub, 1, BT_INTEGER))
+ return false;
if (gfc_array_size (sub, &nelems))
{
@@ -6501,47 +6674,46 @@ gfc_check_image_index (gfc_expr *coarray, gfc_expr *sub)
mpz_clear (nelems);
}
+ if (team_or_team_number)
+ {
+ if (!type_check2 (team_or_team_number, 2, BT_DERIVED, BT_INTEGER)
+ || !scalar_check (team_or_team_number, 2))
+ return false;
+
+ /* Check team is of team_type. */
+ if (team_or_team_number->ts.type == BT_DERIVED
+ && !team_type_check (team_or_team_number, 2))
+ return false;
+ }
+
return true;
}
-
bool
-gfc_check_num_images (gfc_expr *distance, gfc_expr *failed)
+gfc_check_num_images (gfc_expr *team_or_team_number)
{
if (flag_coarray == GFC_FCOARRAY_NONE)
{
- gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
+ gfc_fatal_error ("Coarrays disabled at %L, use %<-fcoarray=%> to enable",
+ gfc_current_intrinsic_where);
return false;
}
- if (distance)
- {
- if (!type_check (distance, 0, BT_INTEGER))
- return false;
-
- if (!nonnegative_check ("DISTANCE", distance))
- return false;
-
- if (!scalar_check (distance, 0))
- return false;
-
- if (!gfc_notify_std (GFC_STD_F2018, "DISTANCE= argument to "
- "NUM_IMAGES at %L", &distance->where))
- return false;
- }
+ if (!team_or_team_number)
+ return true;
- if (failed)
- {
- if (!type_check (failed, 1, BT_LOGICAL))
- return false;
+ if (!gfc_notify_std (GFC_STD_F2008,
+ "%<team%> or %<team_number%> argument to %qs at %L",
+ gfc_current_intrinsic, &team_or_team_number->where))
+ return false;
- if (!scalar_check (failed, 1))
- return false;
+ if (!type_check2 (team_or_team_number, 0, BT_DERIVED, BT_INTEGER)
+ || !scalar_check (team_or_team_number, 0))
+ return false;
- if (!gfc_notify_std (GFC_STD_F2018, "FAILED= argument to "
- "NUM_IMAGES at %L", &failed->where))
- return false;
- }
+ if (team_or_team_number->ts.type == BT_DERIVED
+ && !team_type_check (team_or_team_number, 0))
+ return false;
return true;
}
@@ -6552,98 +6724,126 @@ gfc_check_team_number (gfc_expr *team)
{
if (flag_coarray == GFC_FCOARRAY_NONE)
{
- gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
+ gfc_fatal_error ("Coarrays disabled at %L, use %<-fcoarray=%> to enable",
+ gfc_current_intrinsic_where);
return false;
}
- if (team)
- {
- if (team->ts.type != BT_DERIVED
- || team->ts.u.derived->from_intmod != INTMOD_ISO_FORTRAN_ENV
- || team->ts.u.derived->intmod_sym_id != ISOFORTRAN_TEAM_TYPE)
- {
- gfc_error ("TEAM argument at %L to the intrinsic TEAM_NUMBER "
- "shall be of type TEAM_TYPE", &team->where);
- return false;
- }
- }
- else
- return true;
-
- return true;
+ return !team || (scalar_check (team, 0) && team_type_check (team, 0));
}
bool
-gfc_check_this_image (gfc_expr *coarray, gfc_expr *dim, gfc_expr *distance)
+gfc_check_this_image (gfc_actual_arglist *args)
{
+ gfc_expr *coarray, *dim, *team, *cur;
+
+ coarray = dim = team = NULL;
+
if (flag_coarray == GFC_FCOARRAY_NONE)
{
- gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
+ gfc_fatal_error ("Coarrays disabled at %L, use %<-fcoarray=%> to enable",
+ gfc_current_intrinsic_where);
return false;
}
- if (coarray == NULL && dim == NULL && distance == NULL)
+ /* Shortcut when no arguments are given. */
+ if (!args->expr && !args->next->expr && !args->next->next->expr)
return true;
- if (dim != NULL && coarray == NULL)
- {
- gfc_error ("DIM argument without COARRAY argument not allowed for "
- "THIS_IMAGE intrinsic at %L", &dim->where);
- return false;
- }
+ cur = args->expr;
- if (distance && (coarray || dim))
+ if (cur)
{
- gfc_error ("The DISTANCE argument may not be specified together with the "
- "COARRAY or DIM argument in intrinsic at %L",
- &distance->where);
- return false;
+ gfc_push_suppress_errors ();
+ if (coarray_check (cur, 0))
+ coarray = cur;
+ else if (scalar_check (cur, 2) && team_type_check (cur, 2))
+ team = cur;
+ else
+ {
+ gfc_pop_suppress_errors ();
+ gfc_error ("First argument of %<this_image%> intrinsic at %L must be "
+ "a coarray "
+ "variable or an object of type %<team_type%> from the "
+ "intrinsic module "
+ "%<ISO_FORTRAN_ENV%>",
+ &cur->where);
+ return false;
+ }
+ gfc_pop_suppress_errors ();
}
- /* Assume that we have "this_image (distance)". */
- if (coarray && !gfc_is_coarray (coarray) && coarray->ts.type == BT_INTEGER)
+ cur = args->next->expr;
+ if (cur)
{
- if (dim)
+ gfc_push_suppress_errors ();
+ if (dim_check (cur, 1, true) && cur->corank == 0)
+ dim = cur;
+ else if (scalar_check (cur, 2) && team_type_check (cur, 2))
{
- gfc_error ("Unexpected DIM argument with noncoarray argument at %L",
- &coarray->where);
+ if (team)
+ {
+ gfc_pop_suppress_errors ();
+ goto team_type_error;
+ }
+ team = cur;
+ }
+ else
+ {
+ gfc_pop_suppress_errors ();
+ gfc_error ("Second argument of %<this_image%> intrinsic at %L must "
+ "be an %<INTEGER%> "
+ "typed scalar or an object of type %<team_type%> from the "
+ "intrinsic "
+ "module %<ISO_FORTRAN_ENV%>",
+ &cur->where);
return false;
}
- distance = coarray;
+ gfc_pop_suppress_errors ();
}
- if (distance)
+ cur = args->next->next->expr;
+ if (cur)
{
- if (!type_check (distance, 2, BT_INTEGER))
- return false;
-
- if (!nonnegative_check ("DISTANCE", distance))
- return false;
-
- if (!scalar_check (distance, 2))
- return false;
-
- if (!gfc_notify_std (GFC_STD_F2018, "DISTANCE= argument to "
- "THIS_IMAGE at %L", &distance->where))
+ if (team_type_check (cur, 2) && scalar_check (cur, 2))
+ {
+ if (team)
+ goto team_type_error;
+ team = cur;
+ }
+ else
return false;
+ }
- return true;
+ if (dim != NULL && coarray == NULL)
+ {
+ gfc_error ("%<dim%> argument without %<coarray%> argument not allowed "
+ "for %<this_image%> intrinsic at %L",
+ &dim->where);
+ return false;
}
- if (!coarray_check (coarray, 0))
+ if (dim && !dim_corank_check (dim, coarray))
return false;
- if (dim != NULL)
- {
- if (!dim_check (dim, 1, false))
- return false;
-
- if (!dim_corank_check (dim, coarray))
- return false;
- }
+ if (team
+ && !gfc_notify_std (GFC_STD_F2018,
+ "%<team%> argument to %<this_image%> at %L",
+ &team->where))
+ return false;
+ args->expr = coarray;
+ args->next->expr = dim;
+ args->next->next->expr = team;
return true;
+
+team_type_error:
+ gfc_error (
+ "At most one argument of type %<team_type%> from the intrinsic module "
+ "%<ISO_FORTRAN_ENV%> to %<this_image%> at %L allowed",
+ &cur->where);
+ return false;
}
/* Calculate the sizes for transfer, used by gfc_check_transfer and also
@@ -6842,7 +7042,8 @@ gfc_check_ucobound (gfc_expr *coarray, gfc_expr *dim, gfc_expr *kind)
{
if (flag_coarray == GFC_FCOARRAY_NONE)
{
- gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
+ gfc_fatal_error ("Coarrays disabled at %L, use %<-fcoarray=%> to enable",
+ gfc_current_intrinsic_where);
return false;
}