[Patch,Fortran] PR 40632 - Add CONTIGUOUS attribute (part 1)
Mikael Morin
mikael.morin@sfr.fr
Sat Jun 19 11:34:00 GMT 2010
On 19.06.2010 00:57, Tobias Burnus wrote:
> Tobias Burnus wrote:
>> The patch implements the parsing and the constraint checking. The next
>> step is to use it also for procedure calls and for array operations
>
> This patch now does this; the right-most stride (dim[0]) is now one and
> there is no (un)pack done for procedure calls. Additionally, I added
> module and dump-parse-tree support, which I initially forgot.
>
> While the patch should be OK, I would be happy if someone could
> carefully read the patch; especially, the constraints, the
> simply-contiguous conditions and the trans*c part.
>
> Build and currently regtesting on x86-64-linux.
> OK for the trunk?
>
> Tobias
Hello,
I have little time, so this is FastReview(TM).
> Index: gcc/fortran/interface.c
> ===================================================================
> --- gcc/fortran/interface.c (Revision 161011)
> +++ gcc/fortran/interface.c (Arbeitskopie)
> @@ -1435,6 +1435,16 @@ compare_parameter (gfc_symbol *formal, g
> return 1;
> }
>
> + /* F2008, C1241. */
> + if (formal->attr.pointer && formal->attr.contiguous
> + && !gfc_is_simply_contiguous (actual, true))
> + {
> + if (where)
> + gfc_error ("Actual argument to contiguous pointer dummy '%s' at %L "
> + "must be simply contigous", formal->name, &actual->where);
> + return 0;
> + }
> +
> if ((actual->expr_type != EXPR_NULL || actual->ts.type != BT_UNKNOWN)
> && !gfc_compare_types (&formal->ts, &actual->ts))
> {
> @@ -1502,6 +1512,34 @@ compare_parameter (gfc_symbol *formal, g
> : actual->symtree->n.sym->as->corank);
> return 0;
> }
> +
> + /* F2008, 12.5.2.8. */
> + if (formal->attr.dimension
> + && (formal->attr.contiguous || formal->as->type != AS_ASSUMED_SHAPE)
> + && !gfc_is_simply_contiguous (actual, true))
> + {
> + if (where)
> + gfc_error ("Actual argument to '%s' at %L must be simply "
> + "contiguous", formal->name, &actual->where);
> + return 0;
> + }
> + }
> +
> + /* F2008, C1239/C1240. */
> + if (actual->expr_type == EXPR_VARIABLE
> + && (actual->symtree->n.sym->attr.asynchronous
> + || actual->symtree->n.sym->attr.volatile_)
> + && (formal->attr.asynchronous || formal->attr.volatile_)
> + && actual->rank && !gfc_is_simply_contiguous (actual, true)
> + && ((formal->as->type != AS_ASSUMED_SHAPE && !formal->attr.pointer)
> + || formal->attr.contiguous))
> + {
> + if (where)
> + gfc_error ("Dummy argument '%s' has to be a pointer or assumed-shape "
> + "array without CONTIGUOUS attribute as actual argument at "
> + "%L is not not simply contiguous and both are ASYNCHRONOUS "
> + "or VOLATILE", formal->name, &actual->where);
> + return 0;
> }
The error message is a bit cryptic to me.
> Index: gcc/fortran/expr.c
> ===================================================================
> --- gcc/fortran/expr.c (Revision 161011)
> +++ gcc/fortran/expr.c (Arbeitskopie)
> @@ -4080,3 +4080,95 @@ gfc_has_ultimate_pointer (gfc_expr *e)
> else
> return false;
> }
> +
> +
> +/* Check whether an expression is "simply contiguous", cf. F2008, 6.5.4.
> + Note: A scalar is not regarded as "simply contiguous" by the standard.
> + if bool is not strict, some futher checks are done - for instance,
> + a "(::1)" is accepted. */
> +
> +bool
> +gfc_is_simply_contiguous (gfc_expr *expr, bool strict)
> +{
> + bool colon;
> + int i;
> + gfc_array_ref *ar = NULL;
> + gfc_ref *ref, *part_ref = NULL;
> +
> + if (expr->expr_type == EXPR_FUNCTION)
> + return expr->symtree->n.sym->result->attr.contiguous;
> + else if (expr->expr_type != EXPR_VARIABLE)
> + return false;
> +
> + if (expr->rank == 0)
> + return false;
> +
> + for (ref = expr->ref; ref; ref = ref->next)
> + {
> + if (ref->type == REF_COMPONENT)
> + part_ref = ref;
> + else if (ref->type == REF_SUBSTRING)
> + return false;
> + else
> + {
> + if (ar)
> + return false; /* Array shall be last part-ref. */
I think this should be outside the else block. For array(:)%component cases.
> + if (ref->u.ar.type != AR_ELEMENT)
> + ar = &ref->u.ar;
> + }
> + }
> +
> + if ((part_ref && !part_ref->u.c.component->attr.contiguous
> + && part_ref->u.c.component->attr.pointer)
> + || (!part_ref && !expr->symtree->n.sym->attr.contiguous
> + && (expr->symtree->n.sym->attr.pointer
> + || expr->symtree->n.sym->as->type == AS_ASSUMED_SHAPE)))
> + return false;
> +
> + if (!ar || ar->type == AR_FULL)
> + return true;
> +
> + gcc_assert (ar->type != AR_UNKNOWN);
You can even assert that ar->type == AR_SECTION.
> +
> + /* Check for simply contiguous array */
> + colon = true;
> + for (i = 0; i < ar->dimen; i++)
> + {
> + gcc_assert (ar->dimen_type[i] != DIMEN_UNKNOWN);
> +
> + if (ar->dimen_type[i] == DIMEN_VECTOR)
> + return false;
> +
> + /* Element or section. Following the standard, "(::1)" or - if known at
> + compile time - "(lbound:ubound)" are not simply contigous; if strict
> + is false, they are regarded as simple contiguous. */
> +
> + if (ar->stride[i] && (strict || ar->stride[i]->expr_type != EXPR_CONSTANT
> + || ar->stride[i]->ts.type != BT_INTEGER
> + || mpz_cmp_si (expr->value.integer, 1) != 0))
> + return false;
> +
> + if (ar->start[i]
> + && (strict || ar->start[i]->expr_type != EXPR_CONSTANT
> + || ar->as->lower[i]->expr_type != EXPR_CONSTANT
> + || mpz_cmp (ar->start[i]->value.integer,
> + ar->as->lower[i]->value.integer) != 0))
> + {
> + if (!colon)
> + return false;
> + colon = false;
> + }
> + if (ar->end[i]
> + && (strict || ar->end[i]->expr_type != EXPR_CONSTANT
> + || ar->as->upper[i]->expr_type != EXPR_CONSTANT
> + || mpz_cmp (ar->end[i]->value.integer,
> + ar->as->upper[i]->value.integer) != 0))
> + {
> + if (!colon)
> + return false;
> + colon = false;
> + }
> + }
> +
> + return true;
> +}
I think you are not rejecting the case array(:,1,:)
Otherwise OK.
Thanks,
Mikael
More information about the Gcc-patches
mailing list