+2011-06-20 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/18918
+ * gfortran.h (gfc_check_vardef_context): Update prototype.
+ (iso_fortran_env_symbol): Handle derived types.
+ (symbol_attribute): Add lock_comp.
+ * expr.c (gfc_check_vardef_context): Add LOCK_TYPE check.
+ * interface.c (compare_parameter, gfc_procedure_use): Handle
+ LOCK_TYPE.
+ (compare_actual_formal): Update
+ gfc_check_vardef_context call.
+ * check.c (gfc_check_atomic_def, gfc_check_atomic_ref): Ditto.
+ * intrinsic.c (check_arglist): Ditto.
+ * io.c (resolve_tag, gfc_resolve_dt, gfc_resolve_inquire): Ditto.
+ * iso-fortran-env.def (ISOFORTRAN_LOCK_TYPE): Add.
+ * intrinsic.texi (ISO_FORTRAN_ENV): Document LOCK_TYPE.
+ * module.c (mio_symbol_attribute): Handle lock_comp.
+ (create_derived_type): New function.
+ (use_iso_fortran_env_module): Call it to handle LOCK_TYPE.
+ * parse.c (parse_derived): Add constraint check for LOCK_TYPE.
+ * resolve.c (resolve_symbol, resolve_lock_unlock): Add constraint
+ checks for LOCK_TYPE.
+ (gfc_resolve_iterator, resolve_deallocate_expr,
+ resolve_allocate_expr, resolve_code, resolve_transfer): Update
+ gfc_check_vardef_context call.
+ * trans-stmt.h (gfc_trans_lock_unlock): New prototype.
+ * trans-stmt.c (gfc_trans_lock_unlock): New function.
+ * trans.c (trans_code): Handle LOCK and UNLOCK.
+
2011-06-18 Janus Weil <janus@gcc.gnu.org>
PR fortran/49400
if (scalar_check (atom, 0) == FAILURE || scalar_check (value, 1) == FAILURE)
return FAILURE;
- if (gfc_check_vardef_context (atom, false, NULL) == FAILURE)
+ if (gfc_check_vardef_context (atom, false, false, NULL) == FAILURE)
{
gfc_error ("ATOM argument of the %s intrinsic function at %L shall be "
"definable", gfc_current_intrinsic, &atom->where);
if (scalar_check (value, 0) == FAILURE || scalar_check (atom, 1) == FAILURE)
return FAILURE;
- if (gfc_check_vardef_context (value, false, NULL) == FAILURE)
+ if (gfc_check_vardef_context (value, false, false, NULL) == FAILURE)
{
gfc_error ("VALUE argument of the %s intrinsic function at %L shall be "
"definable", gfc_current_intrinsic, &value->where);
and just the return status (SUCCESS / FAILURE) be requested. */
gfc_try
-gfc_check_vardef_context (gfc_expr* e, bool pointer, const char* context)
+gfc_check_vardef_context (gfc_expr* e, bool pointer, bool alloc_obj,
+ const char* context)
{
gfc_symbol* sym = NULL;
bool is_pointer;
return FAILURE;
}
+ /* F2008, C1303. */
+ if (!alloc_obj
+ && (attr.lock_comp
+ || (e->ts.type == BT_DERIVED
+ && e->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
+ && e->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)))
+ {
+ if (context)
+ gfc_error ("LOCK_TYPE in variable definition context (%s) at %L",
+ context, &e->where);
+ return FAILURE;
+ }
+
/* INTENT(IN) dummy argument. Check this, unless the object itself is
the component of sub-component of a pointer. Obviously,
procedure pointers are of no interest here. */
}
/* Target must be allowed to appear in a variable definition context. */
- if (gfc_check_vardef_context (assoc->target, pointer, NULL) == FAILURE)
+ if (gfc_check_vardef_context (assoc->target, pointer, false, NULL)
+ == FAILURE)
{
if (context)
gfc_error ("Associate-name '%s' can not appear in a variable"
#define NAMED_INTCST(a,b,c,d) a,
#define NAMED_KINDARRAY(a,b,c,d) a,
#define NAMED_FUNCTION(a,b,c,d) a,
+#define NAMED_DERIVED_TYPE(a,b,c,d) a,
typedef enum
{
ISOFORTRANENV_INVALID = -1,
#undef NAMED_INTCST
#undef NAMED_KINDARRAY
#undef NAMED_FUNCTION
+#undef NAMED_DERIVED_TYPE
#define NAMED_INTCST(a,b,c,d) a,
#define NAMED_REALCST(a,b,c) a,
possibly nested. zero_comp is true if the derived type has no
component at all. */
unsigned alloc_comp:1, pointer_comp:1, proc_pointer_comp:1,
- private_comp:1, zero_comp:1, coarray_comp:1;
+ private_comp:1, zero_comp:1, coarray_comp:1, lock_comp:1;
/* This is a temporary selector for SELECT TYPE. */
unsigned select_type_temporary:1;
bool gfc_has_ultimate_pointer (gfc_expr *);
gfc_expr* gfc_build_intrinsic_call (const char*, locus, unsigned, ...);
-gfc_try gfc_check_vardef_context (gfc_expr*, bool, const char*);
+gfc_try gfc_check_vardef_context (gfc_expr*, bool, bool, const char*);
/* st.c */
"contiguous", formal->name, &actual->where);
return 0;
}
- }
+
+ /* F2008, C1303 and C1304. */
+ if (formal->attr.intent != INTENT_INOUT
+ && (((formal->ts.type == BT_DERIVED || formal->ts.type == BT_CLASS)
+ && formal->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
+ && formal->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
+ || formal->attr.lock_comp))
+
+ {
+ if (where)
+ gfc_error ("Actual argument to non-INTENT(INOUT) dummy '%s' at %L, "
+ "which is LOCK_TYPE or has a LOCK_TYPE component",
+ formal->name, &actual->where);
+ return 0;
+ }
+ }
/* F2008, C1239/C1240. */
if (actual->expr_type == EXPR_VARIABLE
: NULL);
if (f->sym->attr.pointer
- && gfc_check_vardef_context (a->expr, true, context)
+ && gfc_check_vardef_context (a->expr, true, false, context)
== FAILURE)
return 0;
- if (gfc_check_vardef_context (a->expr, false, context)
+ if (gfc_check_vardef_context (a->expr, false, false, context)
== FAILURE)
return 0;
}
"for procedure '%s' at %L", sym->name, &a->expr->where);
break;
}
+
+ /* F2008, C1303 and C1304. */
+ if (a->expr
+ && (a->expr->ts.type == BT_DERIVED || a->expr->ts.type == BT_CLASS)
+ && ((a->expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
+ && a->expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
+ || gfc_expr_attr (a->expr).lock_comp))
+ {
+ gfc_error("Actual argument of LOCK_TYPE or with LOCK_TYPE "
+ "component at %L requires an explicit interface for "
+ "procedure '%s'", &a->expr->where, sym->name);
+ break;
+ }
}
return;
: NULL);
/* No pointer arguments for intrinsics. */
- if (gfc_check_vardef_context (actual->expr, false, context)
+ if (gfc_check_vardef_context (actual->expr, false, false, context)
== FAILURE)
return FAILURE;
}
denote that the lock variable is unlocked. (Fortran 2008 or later.)
@end table
+The module provides the following derived type:
+
+@table @asis
+@item @code{LOCK_TYPE}:
+Derived type with private components to be use with the @code{LOCK} and
+@code{UNLOCK} statement. A variable of its type has to be always declared
+as coarray and may not appear in a variable-definition context.
+(Fortran 2008 or later.)
+@end table
+
The module also provides the following intrinsic procedures:
@ref{COMPILER_OPTIONS} and @ref{COMPILER_VERSION}.
char context[64];
sprintf (context, _("%s tag"), tag->name);
- if (gfc_check_vardef_context (e, false, context) == FAILURE)
+ if (gfc_check_vardef_context (e, false, false, context) == FAILURE)
return FAILURE;
}
/* If we are writing, make sure the internal unit can be changed. */
gcc_assert (k != M_PRINT);
if (k == M_WRITE
- && gfc_check_vardef_context (e, false, _("internal unit in WRITE"))
- == FAILURE)
+ && gfc_check_vardef_context (e, false, false,
+ _("internal unit in WRITE")) == FAILURE)
return FAILURE;
}
gfc_try t;
e = gfc_get_variable_expr (gfc_find_sym_in_symtree (n->sym));
- t = gfc_check_vardef_context (e, false, NULL);
+ t = gfc_check_vardef_context (e, false, false, NULL);
gfc_free_expr (e);
if (t == FAILURE)
{ \
char context[64]; \
sprintf (context, _("%s tag with INQUIRE"), (tag)->name); \
- if (gfc_check_vardef_context ((expr), false, context) == FAILURE) \
+ if (gfc_check_vardef_context ((expr), false, false, context) == FAILURE) \
return FAILURE; \
}
INQUIRE_RESOLVE_TAG (&tag_iomsg, inquire->iomsg);
NAMED_FUNCTION (ISOFORTRAN_COMPILER_VERSION, "compiler_version", \
GFC_ISYM_COMPILER_VERSION, GFC_STD_F2008)
+#ifndef NAMED_DERIVED_TYPE
+# define NAMED_DERIVED_TYPE(a,b,c,d)
+#endif
+
+NAMED_DERIVED_TYPE (ISOFORTRAN_LOCK_TYPE, "lock_type", \
+ get_int_kind_from_node (ptr_type_node), GFC_STD_F2008)
#undef NAMED_INTCST
#undef NAMED_KINDARRAY
#undef NAMED_FUNCTION
+#undef NAMED_DERIVED_TYPE
AB_ELEMENTAL, AB_PURE, AB_RECURSIVE, AB_GENERIC, AB_ALWAYS_EXPLICIT,
AB_CRAY_POINTER, AB_CRAY_POINTEE, AB_THREADPRIVATE,
AB_ALLOC_COMP, AB_POINTER_COMP, AB_PROC_POINTER_COMP, AB_PRIVATE_COMP,
- AB_VALUE, AB_VOLATILE, AB_PROTECTED,
+ AB_VALUE, AB_VOLATILE, AB_PROTECTED, AB_LOCK_COMP,
AB_IS_BIND_C, AB_IS_C_INTEROP, AB_IS_ISO_C, AB_ABSTRACT, AB_ZERO_COMP,
AB_IS_CLASS, AB_PROCEDURE, AB_PROC_POINTER, AB_ASYNCHRONOUS, AB_CODIMENSION,
AB_COARRAY_COMP, AB_VTYPE, AB_VTAB, AB_CONTIGUOUS, AB_CLASS_POINTER,
minit ("VALUE", AB_VALUE),
minit ("ALLOC_COMP", AB_ALLOC_COMP),
minit ("COARRAY_COMP", AB_COARRAY_COMP),
+ minit ("LOCK_COMP", AB_LOCK_COMP),
minit ("POINTER_COMP", AB_POINTER_COMP),
minit ("PROC_POINTER_COMP", AB_PROC_POINTER_COMP),
minit ("PRIVATE_COMP", AB_PRIVATE_COMP),
MIO_NAME (ab_attribute) (AB_PRIVATE_COMP, attr_bits);
if (attr->coarray_comp)
MIO_NAME (ab_attribute) (AB_COARRAY_COMP, attr_bits);
+ if (attr->lock_comp)
+ MIO_NAME (ab_attribute) (AB_LOCK_COMP, attr_bits);
if (attr->zero_comp)
MIO_NAME (ab_attribute) (AB_ZERO_COMP, attr_bits);
if (attr->is_class)
case AB_COARRAY_COMP:
attr->coarray_comp = 1;
break;
+ case AB_LOCK_COMP:
+ attr->lock_comp = 1;
+ break;
case AB_POINTER_COMP:
attr->pointer_comp = 1;
break;
}
+/* Add an derived type for a given module. */
+
+static void
+create_derived_type (const char *name, const char *modname,
+ intmod_id module, int id)
+{
+ gfc_symtree *tmp_symtree;
+ gfc_symbol *sym;
+
+ tmp_symtree = gfc_find_symtree (gfc_current_ns->sym_root, name);
+ if (tmp_symtree != NULL)
+ {
+ if (strcmp (modname, tmp_symtree->n.sym->module) == 0)
+ return;
+ else
+ gfc_error ("Symbol '%s' already declared", name);
+ }
+
+ gfc_get_sym_tree (name, gfc_current_ns, &tmp_symtree, false);
+ sym = tmp_symtree->n.sym;
+
+ sym->module = gfc_get_string (modname);
+ sym->from_intmod = module;
+ sym->intmod_sym_id = id;
+ sym->attr.flavor = FL_DERIVED;
+ sym->attr.private_comp = 1;
+ sym->attr.zero_comp = 1;
+ sym->attr.use_assoc = 1;
+}
+
+
/* USE the ISO_FORTRAN_ENV intrinsic module. */
#define NAMED_KINDARRAY(a,b,c,d) { a, b, 0, d },
#include "iso-fortran-env.def"
#undef NAMED_KINDARRAY
+#define NAMED_DERIVED_TYPE(a,b,c,d) { a, b, 0, d },
+#include "iso-fortran-env.def"
+#undef NAMED_DERIVED_TYPE
#define NAMED_FUNCTION(a,b,c,d) { a, b, c, d },
#include "iso-fortran-env.def"
#undef NAMED_FUNCTION
#include "iso-fortran-env.def"
#undef NAMED_KINDARRAY
+#define NAMED_DERIVED_TYPE(a,b,TYPE,STD) \
+ case a:
+#include "iso-fortran-env.def"
+ create_derived_type (u->local_name[0] ? u->local_name
+ : u->use_name,
+ mod, INTMOD_ISO_FORTRAN_ENV,
+ symbol[i].id);
+ break;
+#undef NAMED_DERIVED_TYPE
+
#define NAMED_FUNCTION(a,b,c,d) \
case a:
#include "iso-fortran-env.def"
#include "iso-fortran-env.def"
#undef NAMED_KINDARRAY
+#define NAMED_DERIVED_TYPE(a,b,TYPE,STD) \
+ case a:
+#include "iso-fortran-env.def"
+ create_derived_type (symbol[i].name, mod, INTMOD_ISO_FORTRAN_ENV,
+ symbol[i].id);
+ break;
+#undef NAMED_DERIVED_TYPE
+
#define NAMED_FUNCTION(a,b,c,d) \
case a:
#include "iso-fortran-env.def"
|| (c->attr.coarray_comp && !c->attr.pointer && !c->attr.allocatable))
sym->attr.coarray_comp = 1;
+ /* Looking for lock_type components. */
+ if (c->attr.lock_comp
+ || (sym->ts.type == BT_DERIVED
+ && c->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
+ && c->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE))
+ sym->attr.lock_comp = 1;
+
/* Look for private components. */
if (sym->component_access == ACCESS_PRIVATE
|| c->attr.access == ACCESS_PRIVATE
== FAILURE)
return FAILURE;
- if (gfc_check_vardef_context (iter->var, false, _("iterator variable"))
+ if (gfc_check_vardef_context (iter->var, false, false, _("iterator variable"))
== FAILURE)
return FAILURE;
}
if (pointer
- && gfc_check_vardef_context (e, true, _("DEALLOCATE object")) == FAILURE)
+ && gfc_check_vardef_context (e, true, true, _("DEALLOCATE object"))
+ == FAILURE)
return FAILURE;
- if (gfc_check_vardef_context (e, false, _("DEALLOCATE object")) == FAILURE)
+ if (gfc_check_vardef_context (e, false, true, _("DEALLOCATE object"))
+ == FAILURE)
return FAILURE;
return SUCCESS;
&e->where, &code->expr3->where);
goto failure;
}
+
+ /* Check F2008, C642. */
+ if (code->expr3->ts.type == BT_DERIVED
+ && ((codimension && gfc_expr_attr (code->expr3).lock_comp)
+ || (code->expr3->ts.u.derived->from_intmod
+ == INTMOD_ISO_FORTRAN_ENV
+ && code->expr3->ts.u.derived->intmod_sym_id
+ == ISOFORTRAN_LOCK_TYPE)))
+ {
+ gfc_error ("The source-expr at %L shall neither be of type "
+ "LOCK_TYPE nor have a LOCK_TYPE component if "
+ "allocate-object at %L is a coarray",
+ &code->expr3->where, &e->where);
+ goto failure;
+ }
}
/* Check F08:C629. */
e2 = remove_last_array_ref (e);
t = SUCCESS;
if (t == SUCCESS && pointer)
- t = gfc_check_vardef_context (e2, true, _("ALLOCATE object"));
+ t = gfc_check_vardef_context (e2, true, true, _("ALLOCATE object"));
if (t == SUCCESS)
- t = gfc_check_vardef_context (e2, false, _("ALLOCATE object"));
+ t = gfc_check_vardef_context (e2, false, true, _("ALLOCATE object"));
gfc_free_expr (e2);
if (t == FAILURE)
goto failure;
/* Check the stat variable. */
if (stat)
{
- gfc_check_vardef_context (stat, false, _("STAT variable"));
+ gfc_check_vardef_context (stat, false, false, _("STAT variable"));
if ((stat->ts.type != BT_INTEGER
&& !(stat->ref && (stat->ref->type == REF_ARRAY
gfc_warning ("ERRMSG at %L is useless without a STAT tag",
&errmsg->where);
- gfc_check_vardef_context (errmsg, false, _("ERRMSG variable"));
+ gfc_check_vardef_context (errmsg, false, false, _("ERRMSG variable"));
if ((errmsg->ts.type != BT_CHARACTER
&& !(errmsg->ref
code->ext.dt may be NULL if the TRANSFER is related to
an INQUIRE statement -- but in this case, we are not reading, either. */
if (code->ext.dt && code->ext.dt->dt_io_kind->value.iokind == M_READ
- && gfc_check_vardef_context (exp, false, _("item in READ")) == FAILURE)
+ && gfc_check_vardef_context (exp, false, false, _("item in READ"))
+ == FAILURE)
return;
sym = exp->symtree->n.sym;
static void
resolve_lock_unlock (gfc_code *code)
{
- /* FIXME: Add more lock-variable checks. For now, always reject it.
- Note that ISO_FORTRAN_ENV's LOCK_TYPE is not yet available. */
- /* if (code->expr2->ts.type != BT_DERIVED
- || code->expr2->rank != 0
- || code->expr2->expr_type != EXPR_VARIABLE) */
- gfc_error ("Lock variable at %L must be a scalar of type LOCK_TYPE",
- &code->expr1->where);
+ if (code->expr1->ts.type != BT_DERIVED
+ || code->expr1->expr_type != EXPR_VARIABLE
+ || code->expr1->ts.u.derived->from_intmod != INTMOD_ISO_FORTRAN_ENV
+ || code->expr1->ts.u.derived->intmod_sym_id != ISOFORTRAN_LOCK_TYPE
+ || code->expr1->rank != 0
+ || !(gfc_expr_attr (code->expr1).codimension
+ || gfc_is_coindexed (code->expr1)))
+ gfc_error ("Lock variable at %L must be a scalar coarray of type "
+ "LOCK_TYPE", &code->expr1->where);
/* Check STAT. */
if (code->expr2
gfc_error ("STAT= argument at %L must be a scalar INTEGER variable",
&code->expr2->where);
+ if (code->expr2
+ && gfc_check_vardef_context (code->expr2, false, false,
+ _("STAT variable")) == FAILURE)
+ return;
+
/* Check ERRMSG. */
if (code->expr3
&& (code->expr3->ts.type != BT_CHARACTER || code->expr3->rank != 0
gfc_error ("ERRMSG= argument at %L must be a scalar CHARACTER variable",
&code->expr3->where);
+ if (code->expr3
+ && gfc_check_vardef_context (code->expr3, false, false,
+ _("ERRMSG variable")) == FAILURE)
+ return;
+
/* Check ACQUIRED_LOCK. */
if (code->expr4
&& (code->expr4->ts.type != BT_LOGICAL || code->expr4->rank != 0
|| code->expr4->expr_type != EXPR_VARIABLE))
gfc_error ("ACQUIRED_LOCK= argument at %L must be a scalar LOGICAL "
"variable", &code->expr4->where);
+
+ if (code->expr4
+ && gfc_check_vardef_context (code->expr4, false, false,
+ _("ACQUIRED_LOCK variable")) == FAILURE)
+ return;
}
if (t == FAILURE)
break;
- if (gfc_check_vardef_context (code->expr1, false, _("assignment"))
- == FAILURE)
+ if (gfc_check_vardef_context (code->expr1, false, false,
+ _("assignment")) == FAILURE)
break;
if (resolve_ordinary_assign (code, ns))
array ref may be present on the LHS and fool gfc_expr_attr
used in gfc_check_vardef_context. Remove it. */
e = remove_last_array_ref (code->expr1);
- t = gfc_check_vardef_context (e, true, _("pointer assignment"));
+ t = gfc_check_vardef_context (e, true, false,
+ _("pointer assignment"));
if (t == SUCCESS)
- t = gfc_check_vardef_context (e, false, _("pointer assignment"));
+ t = gfc_check_vardef_context (e, false, false,
+ _("pointer assignment"));
gfc_free_expr (e);
if (t == FAILURE)
break;
sym->ts.u.derived->name) == FAILURE)
return;
+ /* F2008, C1302. */
+ if (sym->ts.type == BT_DERIVED
+ && sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
+ && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE
+ && !sym->attr.codimension)
+ {
+ gfc_error ("Variable '%s' at %L of type LOCK_TYPE must be a coarray",
+ sym->name, &sym->declared_at);
+ return;
+ }
+
/* An assumed-size array with INTENT(OUT) shall not be of a type for which
default initialization is defined (5.1.2.4.4). */
if (sym->ts.type == BT_DERIVED
}
}
+ /* F2008, C542. */
+ if (sym->ts.type == BT_DERIVED && sym->attr.dummy
+ && sym->attr.intent == INTENT_OUT && sym->attr.lock_comp)
+ gfc_error ("Dummy argument '%s' at %L of LOCK_TYPE shall not be "
+ "INTENT(OUT)", sym->name, &sym->declared_at);
+
/* F2008, C526. */
if (((sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.coarray_comp)
|| sym->attr.codimension)
}
+tree
+gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op type ATTRIBUTE_UNUSED)
+{
+ gfc_se se, argse;
+ tree stat = NULL_TREE, lock_acquired = NULL_TREE;
+
+ /* Short cut: For single images without STAT= or LOCK_ACQUIRED
+ return early. (ERRMSG= is always untouched for -fcoarray=single.) */
+ if (!code->expr2 && !code->expr4 && gfc_option.coarray != GFC_FCOARRAY_LIB)
+ return NULL_TREE;
+
+ gfc_init_se (&se, NULL);
+ gfc_start_block (&se.pre);
+
+ if (code->expr2)
+ {
+ gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
+ gfc_init_se (&argse, NULL);
+ gfc_conv_expr_val (&argse, code->expr2);
+ stat = argse.expr;
+ }
+
+ if (code->expr4)
+ {
+ gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
+ gfc_init_se (&argse, NULL);
+ gfc_conv_expr_val (&argse, code->expr4);
+ lock_acquired = argse.expr;
+ }
+
+ if (stat != NULL_TREE)
+ gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
+
+ if (lock_acquired != NULL_TREE)
+ gfc_add_modify (&se.pre, lock_acquired,
+ fold_convert (TREE_TYPE (lock_acquired),
+ boolean_true_node));
+
+ return gfc_finish_block (&se.pre);
+}
+
+
tree
gfc_trans_sync (gfc_code *code, gfc_exec_op type)
{
tree gfc_trans_do_while (gfc_code *);
tree gfc_trans_select (gfc_code *);
tree gfc_trans_sync (gfc_code *, gfc_exec_op);
+tree gfc_trans_lock_unlock (gfc_code *, gfc_exec_op);
tree gfc_trans_forall (gfc_code *);
tree gfc_trans_where (gfc_code *);
tree gfc_trans_allocate (gfc_code *);
res = gfc_trans_sync (code, code->op);
break;
+ case EXEC_LOCK:
+ case EXEC_UNLOCK:
+ res = gfc_trans_lock_unlock (code, code->op);
+ break;
+
case EXEC_FORALL:
res = gfc_trans_forall (code);
break;
+2011-06-20 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/18918
+ * gfortran.dg/coarray_lock_1.f90: Update dg-error.
+ * gfortran.dg/coarray_lock_3.f90: New.
+ * gfortran.dg/coarray/lock_1.f90: New.
+
2011-06-20 Janis Johnson <janisjo@codesourcery.com>
* lib/scandump.exp (scan-dump, scan-dump-times, scan-dump-not,
--- /dev/null
+! { dg-do run }
+!
+! LOCK/UNLOCK check
+!
+! PR fortran/18918
+!
+
+use iso_fortran_env
+implicit none
+
+type(lock_type) :: lock[*]
+integer :: stat
+logical :: acquired
+
+LOCK(lock)
+UNLOCK(lock)
+
+stat = 99
+LOCK(lock, stat=stat)
+if (stat /= 0) call abort()
+stat = 99
+UNLOCK(lock, stat=stat)
+if (stat /= 0) call abort()
+
+if (this_image() == 1) then
+ acquired = .false.
+ LOCK (lock[this_image()], acquired_lock=acquired)
+ if (.not. acquired) call abort()
+ UNLOCK (lock[1])
+end if
+end
+
character(len=3) :: c
logical :: bool
-LOCK (a, stat=s, acquired_lock=bool, errmsg=c) ! { dg-error "must be a scalar of type LOCK_TYPE" }
-UNLOCK (a, stat=s, errmsg=c) ! { dg-error "must be a scalar of type LOCK_TYPE" }
+LOCK (a, stat=s, acquired_lock=bool, errmsg=c) ! { dg-error "must be a scalar coarray of type LOCK_TYPE" }
+UNLOCK (a, stat=s, errmsg=c) ! { dg-error "must be a scalar coarray of type LOCK_TYPE" }
end
--- /dev/null
+! { dg-do compile }
+! { dg-options "-fcoarray=single" }
+!
+!
+! LOCK/LOCK_TYPE checks
+!
+subroutine extends()
+use iso_fortran_env
+type t
+end type t
+type, extends(t) :: t2 ! { dg-error "coarray component, parent type .t. shall also have one" }
+ type(lock_type), allocatable :: c(:)[:]
+end type t2
+end subroutine extends
+
+module m
+ use iso_fortran_env
+
+ type t
+ type(lock_type), allocatable :: x(:)[:]
+ end type t
+
+ type t2
+ type(lock_type), allocatable :: x
+ end type t2
+end module m
+
+subroutine sub(x)
+ use iso_fortran_env
+ type(lock_type), intent(out) :: x[*] ! OK
+end subroutine sub
+
+subroutine sub1(x) ! { dg-error "is INTENT.OUT. and can thus not be an allocatable coarray or have coarray components" }
+ use iso_fortran_env
+ type(lock_type), allocatable, intent(out) :: x(:)[:]
+end subroutine sub1
+
+subroutine sub2(x) ! { dg-error "is INTENT.OUT. and can thus not be an allocatable coarray or have coarray components" }
+ use m
+ type(t), intent(out) :: x
+end subroutine sub2
+
+subroutine sub3(x) ! { dg-error "with coarray component shall be a nonpointer, nonallocatable scalar" }
+ use m
+ type(t), intent(inout) :: x[*]
+end subroutine sub3
+
+subroutine sub4(x)
+ use m
+ type(t2), intent(inout) :: x[*] ! OK
+end subroutine sub4
+
+subroutine lock_test
+ use iso_fortran_env
+ type t
+ end type t
+ type(lock_type) :: lock ! { dg-error "type LOCK_TYPE must be a coarray" }
+end subroutine lock_test
+
+subroutine lock_test2
+ use iso_fortran_env
+ implicit none
+ type t
+ end type t
+ type(t) :: x
+ type(lock_type), save :: lock[*],lock2(2)[*]
+ lock(t) ! { dg-error "Syntax error in LOCK statement" }
+ lock(x) ! { dg-error "must be a scalar coarray of type LOCK_TYPE" }
+ lock(lock)
+ lock(lock2(1))
+ lock(lock2) ! { dg-error "must be a scalar coarray of type LOCK_TYPE" }
+ lock(lock[1]) ! { dg-error "must be a scalar coarray of type LOCK_TYPE" }
+end subroutine lock_test2
+
+
+subroutine lock_test3
+ use iso_fortran_env
+ type(lock_type), save :: a[*], b[*]
+ a = b ! { dg-error "LOCK_TYPE in variable definition context" }
+ b = lock_type() ! { dg-error "LOCK_TYPE in variable definition context" }
+ print *, a ! { dg-error "cannot have PRIVATE components" }
+end subroutine lock_test3
+
+
+subroutine lock_test4
+ use iso_fortran_env
+ type(lock_type), allocatable :: A(:)[:]
+ logical :: ob
+ allocate(A(1)[*])
+ lock(A(1), acquired_lock=ob)
+ unlock(A(1))
+ deallocate(A)
+end subroutine lock_test4
+
+
+subroutine argument_check()
+ use iso_fortran_env
+ type(lock_type), SAVE :: ll[*]
+ call no_interface(ll) ! { dg-error "Actual argument of LOCK_TYPE or with LOCK_TYPE component at .1. requires an explicit interface" }
+ call test(ll) ! { dg-error "non-INTENT.INOUT. dummy .x. at .1., which is LOCK_TYPE or has a LOCK_TYPE component" }
+contains
+ subroutine test(x)
+ type(lock_type), intent(in) :: x[*]
+ end subroutine test
+end subroutine argument_check
+
+! { dg-final { cleanup-modules "m" } }