Message ID | 4D317249.30509@netcologne.de |
---|---|
State | New |
Headers | show |
Thomas Koenig wrote: > the attached patch fixes the PR by inserting additional checks in > resolve.c to catch the invalid array sections. > > PR fortran/38536 > * resolve.c (gfc_iso_c_func_interface): For C_LOC, > check for array sections which are illegal. > > integer(c_int), target :: n(3) > p = c_loc(tt%t%i(1)) ! { dg-error "Array section not permitted" } > p = c_loc(n(1:2)) ! { dg-error "Array section not permitted" } While I agree that "tt%t%i(1)" is invalid as "t" is an array (of size 5), I fail to see why "n(1:2)" is invalid. If I look at the Fortran 2008 standard I just find: "15.2.3.6 C LOC (X)" [...] "Argument. X shall have either the POINTER or TARGET attribute. It shall not be a coindexed object. It shall either be a variable with interoperable type and kind type parameters, or be a scalar, nonpolymorphic variable with no length type parameters. If it is allocatable, it shall be allocated. If it is a pointer, it shall be associated. If it is an array, it shall be contiguous and have nonzero size. It shall not be a zero-length string." "n" is a TARGET, it is not coindexed, has of an interoperable type/kind - and it is an array, which is not only contiguous but even simply contiguous. And it is not a zero-sized string. Thus, I claim that "n(1:2)" is perfectly valid and thus the patch rejects too much. In terms of Fortran 2003 it is more difficult to see. If one reads Richard Maine's answer at http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/4b65b1cd206ce9fe one sees that the standard is rather unclear. While Richard deduces that array slices are not valid, it is by far not obvious and the reason "that array slices would not be interoperable is that an array slice might be noncontiguous" is not an issue in Fortran 2008. Fortran 2008 defines when an array is contiguous (cf. "5.3.7 CONTIGUOUS attribute", paragraph 2 ["An object is contiguous if it is ..."]) - and then can uses the term for C_LOC. Regarding the PR: The problem is that contiguity is not compile-time checkable. A subset is compile-time checkable, this set encompasses "simply contiguous" arrays, defined in Section 6.5.4. For very few additional arrays one can deduce at compile time their contiguity (e.g. "A([1,2])") - but in general, going beyond a simple contiguous check is not possible. Thus, one can essentially do three things: (a) Keep the current status [accepts invalid, which is allowed according to the standard], (b) reject clearly invalid arrays such as "tt%t%i(1)", or (c) warn (or even give an error) if the argument is not simply contiguous ["Warning: Argument to C_LOC might be noncontiguous"]. I am happy with both (b) and (c) (warning) , but not with the current patch - even though "c_loc(n(1:2))" can be written as the equivalent "c_loc(n(1))". (With some trickery in defining "n", it could be also equivalent to "c_loc(n(2)).) Thus, the current patch would not really cause that functionality is lost. Tobias
Am 15.01.2011 11:52, schrieb Tobias Burnus: > "n" is a TARGET, it is not coindexed, has of an interoperable type/kind > - and it is an array, Following Richard's explanation, I don't think it is an array, it is an array section. Should we ask on c.l.f? Thomas
Thomas Koenig wrote: > Am 15.01.2011 11:52, schrieb Tobias Burnus: >> "n" is a TARGET, it is not coindexed, has of an interoperable type/kind >> - and it is an array, > Following Richard's explanation, I don't think it is an array, it is an > array section. I agree that it is an array section, but I maintain that it is also an array according to the following definition: "1.3.4 array - set of scalar data, all of the same type and type parameters, whose individual elements are arranged in a rectangular pattern" > Should we ask on c.l.f? Seemingly, you already did.* And it looks as if Fortran 2008 relaxed the requirements - but don't ask me for the details as I find Fortran 2003 very unclear. Tobias * http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/4b65b1cd206ce9fe
Index: resolve.c =================================================================== --- resolve.c (Revision 168614) +++ resolve.c (Arbeitskopie) @@ -2709,6 +2709,8 @@ gfc_iso_c_func_interface (gfc_symbol *sym, gfc_act } else if (sym->intmod_sym_id == ISOCBINDING_LOC) { + gfc_ref *ref; + /* Make sure we have either the target or pointer attribute. */ if (!arg_attr.target && !arg_attr.pointer) { @@ -2719,6 +2721,23 @@ gfc_iso_c_func_interface (gfc_symbol *sym, gfc_act retval = FAILURE; } + /* Follow references to make sure there are no array + slices. */ + for (ref=args->expr->ref; ref; ref = ref->next) + { + if (ref->type == REF_ARRAY) + { + if (ref->u.ar.type == AR_SECTION + || (ref->u.ar.type != AR_ELEMENT && + ref->next && ref->next->type == REF_COMPONENT)) + { + gfc_error_now ("Array section not permitted in '%s'" + " call at %L", name, &(args->expr->where)); + retval = FAILURE; + } + } + } + /* See if we have interoperable type and type param. */ if (verify_c_interop (arg_ts) == SUCCESS || gfc_check_any_c_kind (arg_ts) == SUCCESS)