Message ID | 4E248B74.1000308@net-b.de |
---|---|
State | New |
Headers | show |
Tobias Burnus wrote: > I would be happy if someone could carefully read the function in > expr.c - and confirm that the second test case ("dg-error" line) is > indeed invalid. I think it is invalid because one has an array element > of a coarray, which is a coarray but which is not simply contiguous. > Thus, if possible cross check that it is indeed not simply contiguous. Seemingly J3 concurs that the current wording does not allow it. Whether it should allow it or not is less clear, cf. PR 45859. (I think it should be made valid.) Tobias
On Monday 18 July 2011 21:37:24 Tobias Burnus wrote: > As the coarray status is nontrivial to check, I have created a function > for that - and I use it now for the interface checking. There are more > cases, where the wrong check is used, leading to accepts-invalid and > rejects-valid issues; however, I would like to track them later. Two minor suggestions: > diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c > index b8eb555..67ac2e5 100644 > --- a/gcc/fortran/expr.c > +++ b/gcc/fortran/expr.c > @@ -4154,6 +4154,74 @@ gfc_is_coindexed (gfc_expr *e) > } > > > +/* Coarrays are variables with a corank but not being coindexed. However, also > + the following is a coarray: A subobject of a coarray is a coarray if it does > + not have any cosubscripts, vector subscripts, allocatable component > + selection, or pointer component selection. (F2008, 2.4.7) */ > + > +bool > +gfc_is_coarray (gfc_expr *e) > +{ > + gfc_ref *ref; > + gfc_symbol *sym; > + gfc_component *comp; > + bool coindexed; > + bool coarray; > + int i; > + > + if (e->expr_type != EXPR_VARIABLE > + && e->expr_type != EXPR_FUNCTION) > + return false; This should not change anything, but I think EXPR_FUNCTION can be discarded because of C523: A coarray shall be a component or a variable that is not a function result. > diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c > index dcf6c4e..fa23de7 100644 > --- a/gcc/fortran/interface.c > +++ b/gcc/fortran/interface.c > @@ -1557,41 +1557,21 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, [...] > + if (formal->attr.codimension && formal->attr.allocatable) > + { > + gfc_ref *last = NULL; > > for (ref = actual->ref; ref; ref = ref->next) > - { > - if (ref->type == REF_ARRAY && ref->u.ar.as->corank > - && ref->u.ar.type != AR_FULL && ref->u.ar.dimen != 0) > - { > - if (where) > - gfc_error ("Actual argument to '%s' at %L must be a coarray " > - "and thus shall not have an array designator", > - formal->name, &ref->u.ar.where); > - return 0; > - } > - if (ref->type == REF_COMPONENT) > - last = ref; > - } > + if (ref->type == REF_COMPONENT) > + last = ref; > > /* F2008, 12.5.2.6. */ > if (formal->attr.allocatable && This formal->attr.allocatable condition is now superfluous. Now about your request: > I would be happy if someone could carefully read the function in expr.c > - and confirm that the second test case ("dg-error" line) is indeed > invalid. I think it is invalid because one has an array element of a > coarray, which is a coarray but which is not simply contiguous. I don't understand what is your concern here; the standard seems pretty clear: 12.5.2.8 (f2008): If the dummy argument is an array coarray that has the CONTIGUOUS attribute or is not of assumed shape, the corresponding actual argument shall be simply contiguous. Thus, invalid indeed. > Thus, if possible cross check that it is indeed not simply contiguous. 6.5.4 (f2008): A section-subscript-list specifies a simply contiguous section if and only if it does not have a vector subscript and • all but the last subscript-triplet is a colon, • the last subscript-triplet does not have a stride, and • _no subscript-triplet is preceded by a section-subscript that is a_ _subscript._ It's not simply contiguous indeed. Wasn't it obvious anyway or did I miss something? So, to sum up, if one sticks to fortran 2008, the test is clearly invalid and... > Build and regtested on x86-64-linux. > OK for the trunk? ... the patch is ok with the two minor changes suggested above. Mikael
On 07/19/2011 05:24 PM, Mikael Morin wrote: > On Monday 18 July 2011 21:37:24 Tobias Burnus wrote: > Now about your request: >> I would be happy if someone could carefully read the function in expr.c >> - and confirm that the second test case ("dg-error" line) is indeed >> invalid. I think it is invalid because one has an array element of a >> coarray, which is a coarray but which is not simply contiguous. > I don't understand what is your concern here; the standard seems pretty clear Well, I was confused about it as passing an array element as actual argument to a dummy argument is OK, while it is not for coarrays. Additionally, there is a test case, which is supposedly valid (and accepted by some compilers) but fails. - And it is not the first time that I fail either to read something obvious as such (mind too much twisted) - or to miss some constraint elsewhere (mind too little twisted). However, in this case, the F2008 standard seems to relatively clearly reject it - though not clearly enough as J3 suggested to edit the text to make it even clearer: http://j3-fortran.org/doc/meeting/193/10-226r2.txt However, in the J3 ballot the modified proposal was rejected - and some want to have the original version back: http://j3-fortran.org/doc/meeting/193/10-226.txt (Cf. comments for F08/0048 at http://j3-fortran.org/doc/year/11/11-006A.txt ) Thus, the standard is not as obvious as one might think ;-) > So, to sum up, if one sticks to fortran 2008, the test is clearly > invalid and.. ... thus the current version rejects it. I think we leave it like that and keep PR 45859 as tracking bug. >> Build and regtested on x86-64-linux. >> OK for the trunk? > ... the patch is ok with the two minor changes suggested above. Committed with the two changes as Rev. 176467. Thanks for the review! Tobias
2011-07-18 Tobias Burnus <burnus@net-b.de> * expr.c (gfc_is_coarray): New function. * gfortran.h (gfc_is_coarray): New prototype. * interface.c (compare_parameter): Use it. 2011-07-18 Tobias Burnus <burnus@net-b.de> * gfortran.dg/coarray_args_1.f90: New. * gfortran.dg/coarray_args_2.f90: New. diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index b8eb555..67ac2e5 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -4154,6 +4154,74 @@ gfc_is_coindexed (gfc_expr *e) } +/* Coarrays are variables with a corank but not being coindexed. However, also + the following is a coarray: A subobject of a coarray is a coarray if it does + not have any cosubscripts, vector subscripts, allocatable component + selection, or pointer component selection. (F2008, 2.4.7) */ + +bool +gfc_is_coarray (gfc_expr *e) +{ + gfc_ref *ref; + gfc_symbol *sym; + gfc_component *comp; + bool coindexed; + bool coarray; + int i; + + if (e->expr_type != EXPR_VARIABLE + && e->expr_type != EXPR_FUNCTION) + return false; + + coindexed = false; + sym = e->symtree->n.sym; + + if (sym->ts.type == BT_CLASS && sym->attr.class_ok) + coarray = CLASS_DATA (sym)->attr.codimension; + else + coarray = sym->attr.codimension; + + for (ref = e->ref; ref; ref = ref->next) + switch (ref->type) + { + case REF_COMPONENT: + comp = ref->u.c.component; + if (comp->attr.pointer || comp->attr.allocatable) + { + coindexed = false; + if (comp->ts.type == BT_CLASS && comp->attr.class_ok) + coarray = CLASS_DATA (comp)->attr.codimension; + else + coarray = comp->attr.codimension; + } + break; + + case REF_ARRAY: + if (!coarray) + break; + + if (ref->u.ar.codimen > 0 && !gfc_ref_this_image (ref)) + { + coindexed = true; + break; + } + + for (i = 0; i < ref->u.ar.dimen; i++) + if (ref->u.ar.dimen_type[i] == DIMEN_VECTOR) + { + coarray = false; + break; + } + break; + + case REF_SUBSTRING: + break; + } + + return coarray && !coindexed; +} + + int gfc_get_corank (gfc_expr *e) { diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index eb01b0e..8fc69d9 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2735,6 +2736,7 @@ bool gfc_is_proc_ptr_comp (gfc_expr *, gfc_component **); bool gfc_ref_this_image (gfc_ref *ref); bool gfc_is_coindexed (gfc_expr *); +bool gfc_is_coarray (gfc_expr *); int gfc_get_corank (gfc_expr *); bool gfc_has_ultimate_allocatable (gfc_expr *); bool gfc_has_ultimate_pointer (gfc_expr *); diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index dcf6c4e..fa23de7 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -1557,41 +1557,21 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, } } - if (formal->attr.codimension) + if (formal->attr.codimension && !gfc_is_coarray (actual)) { - gfc_ref *last = NULL; - - if (actual->expr_type != EXPR_VARIABLE - || !gfc_expr_attr (actual).codimension) - { - if (where) - gfc_error ("Actual argument to '%s' at %L must be a coarray", + if (where) + gfc_error ("Actual argument to '%s' at %L must be a coarray", formal->name, &actual->where); - return 0; - } + return 0; + } - if (gfc_is_coindexed (actual)) - { - if (where) - gfc_error ("Actual argument to '%s' at %L must be a coarray " - "and not coindexed", formal->name, &actual->where); - return 0; - } + if (formal->attr.codimension && formal->attr.allocatable) + { + gfc_ref *last = NULL; for (ref = actual->ref; ref; ref = ref->next) - { - if (ref->type == REF_ARRAY && ref->u.ar.as->corank - && ref->u.ar.type != AR_FULL && ref->u.ar.dimen != 0) - { - if (where) - gfc_error ("Actual argument to '%s' at %L must be a coarray " - "and thus shall not have an array designator", - formal->name, &ref->u.ar.where); - return 0; - } - if (ref->type == REF_COMPONENT) - last = ref; - } + if (ref->type == REF_COMPONENT) + last = ref; /* F2008, 12.5.2.6. */ if (formal->attr.allocatable && @@ -1606,7 +1586,10 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, : actual->symtree->n.sym->as->corank); return 0; } + } + if (formal->attr.codimension) + { /* F2008, 12.5.2.8. */ if (formal->attr.dimension && (formal->attr.contiguous || formal->as->type != AS_ASSUMED_SHAPE) @@ -1633,7 +1616,7 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, formal->name, &actual->where); return 0; } - } + } /* F2008, C1239/C1240. */ if (actual->expr_type == EXPR_VARIABLE --- /dev/null 2011-07-18 07:46:52.518868366 +0200 +++ gcc/gcc/testsuite/gfortran.dg/coarray_args_1.f90 2011-07-18 10:08:58.000000000 +0200 @@ -0,0 +1,20 @@ +! { dg-do compile } +! { dg-options "-fcoarray=single" } +! +! Argument checking +! + implicit none + type t + integer :: i + integer,allocatable :: j + end type t + + type(t), save :: x[*] + + call sub1(x%i) + call sub1(x[1]%i) ! { dg-error "must be a coarray" } +contains + subroutine sub1(y) + integer :: y[*] + end subroutine sub1 +end --- /dev/null 2011-07-18 07:46:52.518868366 +0200 +++ gcc/gcc/testsuite/gfortran.dg/coarray_args_2.f90 2011-07-18 18:59:48.000000000 +0200 @@ -0,0 +1,50 @@ +! { dg-do compile } +! { dg-options "-fcoarray=single" } +! +! Check argument passing. +! Taken from Reinhold Bader's fortran_tests. +! + +module mod_rank_mismatch_02 + implicit none + integer, parameter :: ndim = 2 +contains + subroutine subr(n,w) + integer :: n + real :: w(n,*)[*] + + integer :: k, x + + if (this_image() == 0) then + x = 1.0 + do k = 1, num_images() + if (abs(w(2,1)[k] - x) > 1.0e-5) then + write(*, *) 'FAIL' + error stop + end if + x = x + 1.0 + end do + end if + + end subroutine +end module + +program rank_mismatch_02 + use mod_rank_mismatch_02 + implicit none + real :: a(ndim,2)[*] + + a = 0.0 + a(2,2) = 1.0 * this_image() + + sync all + + call subr(ndim, a(1:1,2)) ! OK + call subr(ndim, a(1,2)) ! { dg-error "must be simply contiguous" } + + if (this_image() == 1) then + write(*, *) 'OK' + end if +end program + +! { dg-final { cleanup-modules "mod_rank_mismatch_02" } }