gfc_typespec ts;
gfc_symbol *sym;
match m;
- locus old_locus, deferred_locus;
+ locus old_locus, deferred_locus, assumed_locus;
bool saw_stat, saw_errmsg, saw_source, saw_mold, saw_deferred, b1, b2, b3;
- bool saw_unlimited = false;
+ bool saw_unlimited = false, saw_assumed = false;
head = tail = NULL;
stat = errmsg = source = mold = tmp = NULL;
}
else
{
+ /* Needed for the F2008:C631 check below. */
+ assumed_locus = gfc_current_locus;
+
if (gfc_match (" :: ") == MATCH_YES)
{
if (!gfc_notify_std (GFC_STD_F2003, "typespec in ALLOCATE at %L",
}
if (ts.type == BT_CHARACTER)
- ts.u.cl->length_from_typespec = true;
+ {
+ if (!ts.u.cl->length)
+ saw_assumed = true;
+ else
+ ts.u.cl->length_from_typespec = true;
+ }
- /* TODO understand why this error does not appear but, instead,
- the derived type is caught as a variable in primary.c. */
- if (gfc_spec_list_type (type_param_spec_list, NULL) != SPEC_EXPLICIT)
+ if (type_param_spec_list
+ && gfc_spec_list_type (type_param_spec_list, NULL)
+ == SPEC_DEFERRED)
{
gfc_error ("The type parameter spec list in the type-spec at "
- "%L cannot contain ASSUMED or DEFERRED parameters",
- &old_locus);
+ "%L cannot contain DEFERRED parameters", &old_locus);
goto cleanup;
}
}
if (impure)
gfc_unset_implicit_pure (NULL);
+ /* F2008:C631 (R626) A type-param-value in a type-spec shall be an
+ asterisk if and only if each allocate-object is a dummy argument
+ for which the corresponding type parameter is assumed. */
+ if (saw_assumed
+ && (tail->expr->ts.deferred
+ || tail->expr->ts.u.cl->length
+ || tail->expr->symtree->n.sym->attr.dummy == 0))
+ {
+ gfc_error ("Incompatible allocate-object at %C for CHARACTER "
+ "type-spec at %L", &assumed_locus);
+ goto cleanup;
+ }
+
if (tail->expr->ts.deferred)
{
saw_deferred = true;
--- /dev/null
+! { dg-do compile }
+! PR fortran/82934
+! PR fortran/83318
+program a
+ character(len=42), allocatable :: f
+ character(len=22), allocatable :: ff
+ call alloc(f, ff)
+ if (len(f) .ne. 42) call abort
+ if (len(ff) .ne. 22) call abort
+contains
+ subroutine alloc( a, b )
+ character(len=*), allocatable :: a
+ character(len=22), allocatable :: b
+ character(len=:), allocatable :: c
+ character, allocatable :: d
+ allocate(character(len=*)::a,b) ! { dg-error "Incompatible allocate-object" }
+ allocate(character(len=*)::c) ! { dg-error "Incompatible allocate-object" }
+ allocate(character(len=*)::d) ! { dg-error "Incompatible allocate-object" }
+ end subroutine
+end program a