http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45586

--- Comment #26 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-01-17 
10:08:13 UTC ---
(In reply to comment #24)
> (In reply to comment #23)
> > We could do the analysis that fixed PR 45777 here, I just don't know
> > where :-)
> > 
> > Could somebody point me to the right place (I presume somewhere in trans-*)?
> 
> $ grep RESTRICT *
> ChangeLog-2009:    instead set DECL_RESTRICTED_P on affected decls.
> trans-decl.c:    DECL_RESTRICTED_P (decl) = 1;
> trans-types.c:  prvoid_type_node = build_qualified_type (pvoid_type_node,
> TYPE_QUAL_RESTRICT);
> trans-types.c:                TYPE_QUAL_RESTRICT);
> trans-types.c:    type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
> trans-types.c:    arraytype = build_qualified_type (arraytype,
> TYPE_QUAL_RESTRICT);
> trans-types.c:        type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
> $
> 
> then if you look at those places, they are guarded with a "if (restricted)"
> condition, so the places you are looking for are those of calls to functions
> expecting an argument named restricted (gfc_build_array_type,
> gfc_get_nodesc_array_type). 
> 
> However, it doesn't look that easy. 
> If I understand the thing correctly, in case you have an entity with a pointer
> or target attribute, you have to build a variant of its base type without the
> restrict attribute. That seems easy. Less easy is that you have to build a
> variant type without the restrict attribute for each of it's sub-components
> too. 
> 
> That is, for
> !!!!!
> type foo
>   integer, allocatable :: bar(:)
> end type foo
> type(foo) :: x
> type(foo), pointer :: y
> 
> call baz (x, y)
> !!!!!
> The type of baz's first actual argument (namely &x) is struct foo * restrict
> but the type of baz's second actual argument (namely &y) is not struct foo *.
> 
> typeof(&x) ==
> struct foo_restrict { 
>   struct integer_array {
>     struct array_bounds {
>       int lbound, ubound, stride;
>     } bounds [];
>     ...
>     integer * restrict data;
>   } bar;
> } * restrict
> 
> whereas
> 
> typeof(&y) ==
> struct foo_norestrict { 
>   struct integer_array {
>     struct array_bounds {
>       int lbound, ubound, stride;
>     } bounds [];
>     ...
>     integer * data;
>   } bar;
> } *
> 
> 
> Note that the data member has lost the restrict too. Thus, when creating such
> pointer qualified types, one should take care not to update the
> sym->backend_decl of the derived type as they are different. That looks like a
> substantial rework. 
> Or maybe drop restrict all together on the type for correctness.

Indeed when we introduced the restrict handling to the Fortran frontend
we thought that the above case would not happen, thus that the testcase
in question would be not a valid Fortran program.  At the moment
we probably even could generate a testcase that generates wrong-code
(when the ICE silences itself with release-checking).  This means that
simply trying to make it not ICE is probably wrong and simply hides
the real issue (which the ICE shows).

It is, btw, a sign of bad Fortran language design and makes the point
of the pointer/target attributes moot.

What we could do is drop restrict qualifications for all aggregate
types.  At least such funny games do not seem possible with mere
toplevel arrays or scalars, right?

> By the way, does the middle-end support creating a variant of a type with a
> sub-component restrict (un)qualified ?

No.  For type variants all the fields are usually shared, you'd have to
create a deep copy.

Reply via email to