[Patch, fortran] PR20779 and PR20891 - allocation of STAT or specification variables in same call
Grigory Zagorodnev
grigory_zagorodnev@linux.intel.com
Wed Oct 4 10:14:00 GMT 2006
Hi!
This patch causes compilation failure on SPEC cpu2000/facerec.
Below is the minimal reproducer:
Subroutine ReadParameters (Album)
Implicit NONE
Type GalleryP
Integer :: NoOfEntries
Character(80), Pointer :: FileName (:)
End Type GalleryP
Type(GalleryP), Intent(Out) :: Album
Allocate (Album%FileName (Album%NoOfEntries))
end
Error message:
In file small2.f90:10
Allocate (Album%FileName (Album%NoOfEntries))
1
Error: 'album' must not appear an the array specification at (1) in the
same ALLOCATE statement where it is itself allocated
- Grigory
Paul Thomas wrote:
> Bother! Sorry about forgetting the patch.
>
> Paul
>
>> :ADDPATCH fortran:
>>
>> This patch provides a diagnostic of standard violating code, which has:
>>
>> allocate (i, x(i)) or allocate (i, stat = i) ;
>>
>> ie. allocation of objects used in specification expressions or of the
>> stat variable, within the same allocate statement. The bit of the
>> patch that deals with the stat variable being allocated is straight
>> forward; each new variable to be allocated has its symbol checked
>> against the symbol for stat. If the two are the same, this is an
>> error. The specification expressions are a bit more complicated; each
>> symbol to be allocated is checked by a new recursive function against
>> the symbols referenced in all the specification expressions in the
>> allocate statement. The testcase combines those received from each
>> reporter.
>>
>> Regtested on FC5/Athlon - OK for trunk and 4.1?
>>
>> Paul
>>
>> 2006-09-17 Paul Thomas <pault@gcc.gnu.org>
>>
>> PR fortran/20779
>> PR fortran/20891
>> * resolve.c (find_sym_in_expr): New function that returns true
>> if a symbol is found in an expression.
>> (resolve_allocate_expr): Check whether the STAT variable is
>> itself allocated in the same statement. Use the call above to
>> check whether any of the allocated arrays are used in array
>> specifications in the same statement.
>>
>> 2006-09-17 Paul Thomas <pault@gcc.gnu.org>
>>
>> PR fortran/20779
>> PR fortran/20891
>> * gfortran.dg/alloc_alloc_expr_1.f90: New test.
>>
>>
>>
>
>
> ------------------------------------------------------------------------
>
> Index: gcc/fortran/resolve.c
> ===================================================================
> --- gcc/fortran/resolve.c (révision 116697)
> +++ gcc/fortran/resolve.c (copie de travail)
> @@ -3308,6 +3308,81 @@
> return SUCCESS;
> }
>
> +/* Returns true if the expression e contains a reference the symbol sym. */
> +static bool
> +find_sym_in_expr (gfc_symbol *sym, gfc_expr *e)
> +{
> + gfc_actual_arglist *arg;
> + gfc_ref *ref;
> + int i;
> + bool rv = false;
> +
> + if (e == NULL)
> + return rv;
> +
> + switch (e->expr_type)
> + {
> + case EXPR_FUNCTION:
> + for (arg = e->value.function.actual; arg; arg = arg->next)
> + rv = rv || find_sym_in_expr (sym, arg->expr);
> + break;
> +
> + /* If the variable is not the same as the dependent, 'sym', and
> + it is not marked as being declared and it is in the same
> + namespace as 'sym', add it to the local declarations. */
> + case EXPR_VARIABLE:
> + if (sym == e->symtree->n.sym)
> + return true;
> + break;
> +
> + case EXPR_OP:
> + rv = rv || find_sym_in_expr (sym, e->value.op.op1);
> + rv = rv || find_sym_in_expr (sym, e->value.op.op2);
> + break;
> +
> + default:
> + break;
> + }
> +
> + if (e->ref)
> + {
> + for (ref = e->ref; ref; ref = ref->next)
> + {
> + switch (ref->type)
> + {
> + case REF_ARRAY:
> + for (i = 0; i < ref->u.ar.dimen; i++)
> + {
> + rv = rv || find_sym_in_expr (sym, ref->u.ar.start[i]);
> + rv = rv || find_sym_in_expr (sym, ref->u.ar.end[i]);
> + rv = rv || find_sym_in_expr (sym, ref->u.ar.stride[i]);
> + }
> + break;
> +
> + case REF_SUBSTRING:
> + rv = rv || find_sym_in_expr (sym, ref->u.ss.start);
> + rv = rv || find_sym_in_expr (sym, ref->u.ss.end);
> + break;
> +
> + case REF_COMPONENT:
> + if (ref->u.c.component->ts.type == BT_CHARACTER
> + && ref->u.c.component->ts.cl->length->expr_type
> + != EXPR_CONSTANT)
> + rv = rv || find_sym_in_expr (sym, ref->u.c.component->ts.cl->length);
> +
> + if (ref->u.c.component->as)
> + for (i = 0; i < ref->u.c.component->as->rank; i++)
> + {
> + rv = rv || find_sym_in_expr (sym, ref->u.c.component->as->lower[i]);
> + rv = rv || find_sym_in_expr (sym, ref->u.c.component->as->upper[i]);
> + }
> + break;
> + }
> + }
> + }
> + return rv;
> +}
> +
>
> /* Given the expression node e for an allocatable/pointer of derived type to be
> allocated, get the expression node to be initialized afterwards (needed for
> @@ -3352,10 +3427,17 @@
> gfc_array_ref *ar;
> gfc_code *init_st;
> gfc_expr *init_e;
> + gfc_symbol *sym;
> + gfc_alloc *a;
>
> if (gfc_resolve_expr (e) == FAILURE)
> return FAILURE;
>
> + if (code->expr && code->expr->expr_type == EXPR_VARIABLE)
> + sym = code->expr->symtree->n.sym;
> + else
> + sym = NULL;
> +
> /* Make sure the expression is allocatable or a pointer. If it is
> pointer, the next-to-last reference must be a pointer. */
>
> @@ -3376,6 +3458,14 @@
> pointer = e->symtree->n.sym->attr.pointer;
> dimension = e->symtree->n.sym->attr.dimension;
>
> + if (sym == e->symtree->n.sym)
> + {
> + gfc_error ("The STAT variable '%s' in an ALLOCATE statement must "
> + "not be allocated in the same statement at %L",
> + sym->name, &e->where);
> + return FAILURE;
> + }
> +
> for (ref = e->ref; ref; ref2 = ref, ref = ref->next)
> switch (ref->type)
> {
> @@ -3438,8 +3528,8 @@
> return FAILURE;
> }
>
> - if (ref2->u.ar.type == AR_ELEMENT)
> - return SUCCESS;
> +/* if (ref2->u.ar.type == AR_ELEMENT)
> + return SUCCESS;*/
>
> /* Make sure that the array section reference makes sense in the
> context of an ALLOCATE specification. */
> @@ -3447,25 +3537,45 @@
> ar = &ref2->u.ar;
>
> for (i = 0; i < ar->dimen; i++)
> - switch (ar->dimen_type[i])
> - {
> - case DIMEN_ELEMENT:
> - break;
> + {
> + if (ref2->u.ar.type == AR_ELEMENT)
> + goto check_symbols;
>
> - case DIMEN_RANGE:
> - if (ar->start[i] != NULL
> - && ar->end[i] != NULL
> - && ar->stride[i] == NULL)
> + switch (ar->dimen_type[i])
> + {
> + case DIMEN_ELEMENT:
> break;
>
> - /* Fall Through... */
> + case DIMEN_RANGE:
> + if (ar->start[i] != NULL
> + && ar->end[i] != NULL
> + && ar->stride[i] == NULL)
> + break;
>
> - case DIMEN_UNKNOWN:
> - case DIMEN_VECTOR:
> - gfc_error ("Bad array specification in ALLOCATE statement at %L",
> - &e->where);
> - return FAILURE;
> - }
> + /* Fall Through... */
> +
> + case DIMEN_UNKNOWN:
> + case DIMEN_VECTOR:
> + gfc_error ("Bad array specification in ALLOCATE statement at %L",
> + &e->where);
> + return FAILURE;
> + }
> +
> +check_symbols:
> +
> + for (a = code->ext.alloc_list; a; a = a->next)
> + {
> + sym = a->expr->symtree->n.sym;
> + if ((ar->start[i] != NULL && find_sym_in_expr (sym, ar->start[i]))
> + || (ar->end[i] != NULL && find_sym_in_expr (sym, ar->end[i])))
> + {
> + gfc_error ("'%s' must not appear an the array specification at "
> + "%L in the same ALLOCATE statement where it is "
> + "itself allocated", sym->name, &ar->where);
> + return FAILURE;
> + }
> + }
> + }
>
> return SUCCESS;
> }
> Index: gcc/testsuite/gfortran.dg/alloc_alloc_expr_1.f90
> ===================================================================
> --- gcc/testsuite/gfortran.dg/alloc_alloc_expr_1.f90 (révision 0)
> +++ gcc/testsuite/gfortran.dg/alloc_alloc_expr_1.f90 (révision 0)
> @@ -0,0 +1,29 @@
> +! { dg-do compile }
> +program fc011
> +! Tests fix for PR20779 and PR20891.
> +! Submitted by Walt Brainerd, The Fortran Company
> +! and by Joost VandeVondele <jv244@cam.ac.uk>
> +
> +! This program violates requirements of 6.3.1 of the F95 standard.
> +
> +! An allocate-object, or a subobject of an allocate-object, shall not appear
> +! in a bound in the same ALLOCATE statement. The stat-variable shall not appear
> +! in a bound in the same ALLOCATE statement.
> +
> +! The stat-variable shall not be allocated within the ALLOCATE statement in which
> +! it appears; nor shall it depend on the value, bounds, allocation status, or
> +! association status of any allocate-object or subobject of an allocate-object
> +! allocated in the same statement.
> +
> + integer, pointer :: PTR
> + integer, allocatable :: ALLOCS(:)
> +
> + allocate (PTR, stat=PTR) ! { dg-error "allocated in the same statement" }
> +
> + allocate (ALLOCS(10),stat=ALLOCS(1)) ! { dg-error "allocated in the same statement" }
> +
> + ALLOCATE(PTR,ALLOCS(PTR)) ! { dg-error "same ALLOCATE statement" }
> +
> + print *, 'This program has three errors', PTR, ALLOC(1)
> +
> +end program fc011
>
More information about the Fortran
mailing list