Reported by Ian Bush in comp.lang.fortran, http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/71338937cf348f26 b = c_loc( aa( 1 ) ) 1 Error: Assumed-shape array 'aa' at (1) cannot be an argument to the procedure 'c_loc' because it is not C interoperable Program gf Use iso_c_binding Real( c_double ), Dimension( 1:10 ), Target :: a Call test( a ) Contains Subroutine test( aa ) Real( c_double ), Dimension( : ), Target :: aa Type( c_ptr ), Pointer :: b b = c_loc( aa( 1 ) ) End Subroutine test End Program gf
This allows the code to compile, but one then gets a segfault or the right answer depending on memory layout. I think trans-expr.c(conv_isocbinding_procedure) needs to be updated as well, but don't know what needs to be done (yet). Index: resolve.c =================================================================== --- resolve.c (revision 178329) +++ resolve.c (working copy) @@ -2809,7 +2809,8 @@ gfc_iso_c_func_interface (gfc_symbol *sy interoperable. */ if (args_sym && args_sym->attr.dimension) { - if (args_sym->as->type == AS_ASSUMED_SHAPE) + if (args_sym->as->type == AS_ASSUMED_SHAPE + && args->expr->ref->u.ar.type != AR_ELEMENT) { gfc_error ("Assumed-shape array '%s' at %L " "cannot be an argument to the " troutmask:sgk[215] gfc4x -o z foo.f90 && ./z Calling test() c_loc(aa) = 140737488344288 troutmask:sgk[216] gfc4x -o z foo.f90 && ./z Segmentation fault (core dumped) program gf use iso_c_binding real(c_double), dimension(1:10), target :: a ! a = 42 ! print *, 'Calling test()' call test(a) contains subroutine test(aa) real(c_double), dimension(:), target :: aa type(c_ptr), pointer :: b b = c_loc(aa(1)) print '(A,I0)', 'c_loc(aa) = ', b end subroutine test end program gf
(In reply to comment #1) > This allows the code to compile, but one then gets a segfault > or the right answer depending on memory layout. I think > trans-expr.c(conv_isocbinding_procedure) needs to be updated > as well, but don't know what needs to be done (yet). It might be that it accesses the descriptor instead of desc.data. > - if (args_sym->as->type == AS_ASSUMED_SHAPE) > + if (args_sym->as->type == AS_ASSUMED_SHAPE > + && args->expr->ref->u.ar.type != AR_ELEMENT) > { > gfc_error ("Assumed-shape array '%s' at %L " > "cannot be an argument to the " I think one should use the opportunity to update it to Fortran 2008, which allows also assumed/deferred-shape arrays - if they are contiguous: F2008, 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." Note: It talks about "contiguous" and not "simply contiguous", which means that it is not compile-time checkable (unless strides are used or a vector index). I think there is also a coindexed check missing. Fortran 2003 had in 15.1.2.5 C LOC (X): "Argument. X shall either (1) have interoperable type and type parameters and be (a) a variable that has the TARGET attribute and is interoperable, (b) an allocated allocatable variable that has the TARGET attribute and is not an array of zero size, or (c) an associated scalar pointer, or (2) be a nonpolymorphic scalar, have no length type parameters, and be (a) a nonallocatable, nonpointer variable that has the TARGET attribute, (b) an allocated allocatable variable that has the TARGET attribute, or (c) an associated pointer."
Author: burnus Date: Mon Mar 25 15:40:26 2013 New Revision: 197053 URL: http://gcc.gnu.org/viewcvs?rev=197053&root=gcc&view=rev Log: 2013-03-25 Tobias Burnus <burnus@net-b.de> PR fortran/38536 PR fortran/38813 PR fortran/38894 PR fortran/39288 PR fortran/40963 PR fortran/45824 PR fortran/47023 PR fortran/47034 PR fortran/49023 PR fortran/50269 PR fortran/50612 PR fortran/52426 PR fortran/54263 PR fortran/55343 PR fortran/55444 PR fortran/55574 PR fortran/56079 PR fortran/56378 * check.c (gfc_var_strlen): Properly handle 0-sized string. (gfc_check_c_sizeof): Use is_c_interoperable, add checks. (is_c_interoperable, gfc_check_c_associated, gfc_check_c_f_pointer, gfc_check_c_f_procpointer, gfc_check_c_funloc, gfc_check_c_loc): New functions. * expr.c (check_inquiry): Add c_sizeof, compiler_version and compiler_options. (gfc_check_pointer_assign): Refine function result check. gfortran.h (gfc_isym_id): Add GFC_ISYM_C_ASSOCIATED, GFC_ISYM_C_F_POINTER, GFC_ISYM_C_F_PROCPOINTER, GFC_ISYM_C_FUNLOC, GFC_ISYM_C_LOC. (iso_fortran_env_symbol, iso_c_binding_symbol): Handle NAMED_SUBROUTINE. (generate_isocbinding_symbol): Update prototype. (get_iso_c_sym): Remove. (gfc_isym_id_by_intmod, gfc_isym_id_by_intmod_sym): New prototypes. * intrinsic.c (gfc_intrinsic_subroutine_by_id): New function. (gfc_intrinsic_sub_interface): Use it. (add_functions, add_subroutines): Add missing C-binding intrinsics. (gfc_intrinsic_func_interface): Add special case for c_loc. gfc_isym_id_by_intmod, gfc_isym_id_by_intmod_sym): New functions. (gfc_intrinsic_func_interface, gfc_intrinsic_sub_interface): Use them. * intrinsic.h (gfc_check_c_associated, gfc_check_c_f_pointer, gfc_check_c_f_procpointer, gfc_check_c_funloc, gfc_check_c_loc, gfc_resolve_c_loc, gfc_resolve_c_funloc): New prototypes. * iresolve.c (gfc_resolve_c_loc, gfc_resolve_c_funloc): New functions. * iso-c-binding.def: Split PROCEDURE into NAMED_SUBROUTINE and NAMED_FUNCTION. * iso-fortran-env.def: Add NAMED_SUBROUTINE for completeness. * module.c (create_intrinsic_function): Support subroutines and derived-type results. (use_iso_fortran_env_module): Update calls. (import_iso_c_binding_module): Ditto; update calls to generate_isocbinding_symbol. * resolve.c (find_arglists): Skip for intrinsic symbols. (gfc_resolve_intrinsic): Find intrinsic subs via id. (is_scalar_expr_ptr, gfc_iso_c_func_interface, set_name_and_label, gfc_iso_c_sub_interface): Remove. (resolve_function, resolve_specific_s0): Remove calls to those. (resolve_structure_cons): Fix handling. * symbol.c (gen_special_c_interop_ptr): Update c_ptr/c_funptr generation. (gen_cptr_param, gen_fptr_param, gen_shape_param, build_formal_args, get_iso_c_sym): Remove. (std_for_isocbinding_symbol): Handle NAMED_SUBROUTINE. (generate_isocbinding_symbol): Support hidden symbols and using c_ptr/c_funptr symtrees for nullptr defs. * target-memory.c (gfc_target_encode_expr): Fix handling of c_ptr/c_funptr. * trans-expr.c (conv_isocbinding_procedure): Remove. (gfc_conv_procedure_call): Remove call to it. (gfc_trans_subcomponent_assign, gfc_conv_expr): Update handling of c_ptr/c_funptr. * trans-intrinsic.c (conv_isocbinding_function, conv_isocbinding_subroutine): New. (gfc_conv_intrinsic_function, gfc_conv_intrinsic_subroutine): Call them. * trans-io.c (transfer_expr): Fix handling of c_ptr/c_funptr. * trans-types.c (gfc_typenode_for_spec, gfc_get_derived_type): Ditto. (gfc_init_c_interop_kinds): Handle NAMED_SUBROUTINE. 2013-03-25 Tobias Burnus <burnus@net-b.de> PR fortran/38536 PR fortran/38813 PR fortran/38894 PR fortran/39288 PR fortran/40963 PR fortran/45824 PR fortran/47023 PR fortran/47034 PR fortran/49023 PR fortran/50269 PR fortran/50612 PR fortran/52426 PR fortran/54263 PR fortran/55343 PR fortran/55444 PR fortran/55574 PR fortran/56079 PR fortran/56378 * gfortran.dg/c_assoc_2.f03: Update dg-error wording. * gfortran.dg/c_f_pointer_shape_test.f90: Ditto. * gfortran.dg/c_f_pointer_shape_tests_3.f03: Ditto. * gfortran.dg/c_f_pointer_tests_5.f90: Ditto. * gfortran.dg/c_funloc_tests_2.f03: Ditto. * gfortran.dg/c_funloc_tests_5.f03: Ditto. * gfortran.dg/c_funloc_tests_6.f90: Ditto. * gfortran.dg/c_loc_tests_10.f03: Add -std=f2008. * gfortran.dg/c_loc_tests_11.f03: Ditto, update dg-error. * gfortran.dg/c_loc_tests_16.f90: Ditto. * gfortran.dg/c_loc_tests_4.f03: Ditto. * gfortran.dg/c_loc_tests_15.f90: Update dg-error wording. * gfortran.dg/c_loc_tests_3.f03: Valid since F2003 TC5. * gfortran.dg/c_loc_tests_8.f03: Ditto. * gfortran.dg/c_ptr_tests_14.f90: Update scan-tree-dump-times. * gfortran.dg/c_ptr_tests_15.f90: Ditto. * gfortran.dg/c_sizeof_1.f90: Fix invalid code. * gfortran.dg/iso_c_binding_init_expr.f03: Update dg-error wording. * gfortran.dg/pr32601_1.f03: Ditto. * gfortran.dg/storage_size_2.f08: Remove dg-error. * gfortran.dg/blockdata_7.f90: New. * gfortran.dg/c_assoc_4.f90: New. * gfortran.dg/c_f_pointer_tests_6.f90: New. * gfortran.dg/c_f_pointer_tests_7.f90: New. * gfortran.dg/c_funloc_tests_8.f90: New. * gfortran.dg/c_loc_test_17.f90: New. * gfortran.dg/c_loc_test_18.f90: New. * gfortran.dg/c_loc_test_19.f90: New. * gfortran.dg/c_loc_test_20.f90: New. * gfortran.dg/c_sizeof_5.f90: New. * gfortran.dg/iso_c_binding_rename_3.f90: New. * gfortran.dg/transfer_resolve_2.f90: New. * gfortran.dg/transfer_resolve_3.f90: New. * gfortran.dg/transfer_resolve_4.f90: New. * gfortran.dg/pr32601.f03: Update dg-error. * gfortran.dg/c_ptr_tests_13.f03: Update dg-error. * gfortran.dg/c_ptr_tests_9.f03: Fix test case. Added: trunk/gcc/testsuite/gfortran.dg/blockdata_7.f90 trunk/gcc/testsuite/gfortran.dg/c_assoc_4.f90 trunk/gcc/testsuite/gfortran.dg/c_f_pointer_tests_6.f90 trunk/gcc/testsuite/gfortran.dg/c_f_pointer_tests_7.f90 trunk/gcc/testsuite/gfortran.dg/c_funloc_tests_8.f90 trunk/gcc/testsuite/gfortran.dg/c_loc_test_17.f90 trunk/gcc/testsuite/gfortran.dg/c_loc_test_18.f90 trunk/gcc/testsuite/gfortran.dg/c_loc_test_19.f90 trunk/gcc/testsuite/gfortran.dg/c_loc_test_20.f90 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_17.f90 trunk/gcc/testsuite/gfortran.dg/c_sizeof_5.f90 trunk/gcc/testsuite/gfortran.dg/iso_c_binding_rename_3.f90 trunk/gcc/testsuite/gfortran.dg/transfer_resolve_2.f90 trunk/gcc/testsuite/gfortran.dg/transfer_resolve_3.f90 trunk/gcc/testsuite/gfortran.dg/transfer_resolve_4.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/check.c trunk/gcc/fortran/expr.c trunk/gcc/fortran/gfortran.h trunk/gcc/fortran/intrinsic.c trunk/gcc/fortran/intrinsic.h trunk/gcc/fortran/iresolve.c trunk/gcc/fortran/iso-c-binding.def trunk/gcc/fortran/iso-fortran-env.def trunk/gcc/fortran/module.c trunk/gcc/fortran/resolve.c trunk/gcc/fortran/symbol.c trunk/gcc/fortran/target-memory.c trunk/gcc/fortran/trans-expr.c trunk/gcc/fortran/trans-intrinsic.c trunk/gcc/fortran/trans-io.c trunk/gcc/fortran/trans-types.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/c_assoc_2.f03 trunk/gcc/testsuite/gfortran.dg/c_f_pointer_shape_test.f90 trunk/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_3.f03 trunk/gcc/testsuite/gfortran.dg/c_f_pointer_tests_5.f90 trunk/gcc/testsuite/gfortran.dg/c_funloc_tests_2.f03 trunk/gcc/testsuite/gfortran.dg/c_funloc_tests_5.f03 trunk/gcc/testsuite/gfortran.dg/c_funloc_tests_6.f90 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_10.f03 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_11.f03 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_15.f90 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_16.f90 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_3.f03 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_4.f03 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_8.f03 trunk/gcc/testsuite/gfortran.dg/c_ptr_tests_13.f03 trunk/gcc/testsuite/gfortran.dg/c_ptr_tests_14.f90 trunk/gcc/testsuite/gfortran.dg/c_ptr_tests_15.f90 trunk/gcc/testsuite/gfortran.dg/c_ptr_tests_9.f03 trunk/gcc/testsuite/gfortran.dg/c_sizeof_1.f90 trunk/gcc/testsuite/gfortran.dg/iso_c_binding_init_expr.f03 trunk/gcc/testsuite/gfortran.dg/pr32601.f03 trunk/gcc/testsuite/gfortran.dg/pr32601_1.f03 trunk/gcc/testsuite/gfortran.dg/storage_size_2.f08
FIXED on the 4.9 trunk.
(In reply to comment #4) > FIXED on the 4.9 trunk. Is this going to be ported back to earlier releases? It's kind of a biggie for me...
(In reply to comment #4) > FIXED on the 4.9 trunk. Are we sure? When running the code example given in comment #1, I get a segfault. Moreover, the following subroutine won't compile when using the '-std=f2008' flag: subroutine test_contig (a) use ISO_C_BINDING real, intent(in), contiguous, target :: a(:) type(C_PTR) :: b b = C_LOC(a) end subroutine test_contig The error message is: test_contig.f90:9.12: b = C_LOC(a) 1 Error: TS 29113: Noninteroperable array at (1) as argument to C_LOC: Only explicit-size and assumed-size arrays are interoperable My understanding of the F2008 standard is that assumed-shape arrays with the contiguous attribute are interoperable -- hence, I'm not sure this error message is correct. If I change the std flag to f2008ts, then the routine compiles OK; but the TS extension shouldn't be required here. gfortran -v: Using built-in specs. COLLECT_GCC=/Applications/madsdk/bin/gfortran.exec COLLECT_LTO_WRAPPER=/Applications/madsdk/libexec/gcc/x86_64-apple-darwin11.4.2/4.9.0/lto-wrapper Target: x86_64-apple-darwin11.4.2 Configured with: ./configure CC='gcc -D_FORTIFY_SOURCE=0' --build=x86_64-apple-darwin11.4.2 --prefix=/Applications/madsdk --with-gmp=/Applications/madsdk --with-mpfr=/Applications/madsdk --with-mpc=/Applications/madsdk --enable-languages=c,c++,fortran --disable-multilib Thread model: posix gcc version 4.9.0 20130401 (experimental) (GCC)
REOPEN (In reply to comment #5) > Is this going to be ported back to earlier releases? It's kind of a biggie for > me... Probably not - it is a rather large change - and, hence, it might cause regressions. (In reply to comment #6) > Are we sure? When running the code example given in comment #1, I get a > segfault. Yes, something seems to be still broken. > Moreover, the following subroutine won't compile when using the '-std=f2008' > flag: > real, intent(in), contiguous, target :: a(:) > b = C_LOC(a) > > The error message is: > test_contig.f90:9.12: > b = C_LOC(a) > 1 > Error: TS 29113: Noninteroperable array at (1) as argument to C_LOC: Only > explicit-size and assumed-size arrays are interoperable > > My understanding of the F2008 standard is that assumed-shape arrays with the > contiguous attribute are interoperable Well, Fortran 2008 has: "A Fortran variable that is a named array is interoperable if and only if its type and type parameters are interoperable, it is not a coarray, it is of explicit shape or assumed size, and if it is of type character its length is not ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assumed or declared by an expression that is not a constant expression." ("15.3.6 Interoperability of array variables") Thus, it is definitely not interoperable. But the real question is whether it is permitted for C_LOC. From "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." I think the crucial part is: "with interoperable type and kind type parameter" - which is different to the other intrinsics, which require "an interoperable data entity". Thus, it seems to be permitted in C_LOC. Thanks for testing.
(In reply to comment #7) > (In reply to comment #6) > > Are we sure? When running the code example given in comment #1, I get a > > segfault. > Yes, something seems to be still broken. Actually, the compiler generates the correct code. The problem with the test case of comment 0 and comment 1 is that "b" is a pointer but never allocated. It works if one either removes "pointer" from the declaration of "b" or adds an "allocate(b)".
Author: burnus Date: Thu Apr 4 07:22:24 2013 New Revision: 197468 URL: http://gcc.gnu.org/viewcvs?rev=197468&root=gcc&view=rev Log: 2013-04-04 Tobias Burnus <burnus@net-b.de> PR fortran/50269 * gcc/fortran/check.c (is_c_interoperable, gfc_check_c_loc): Correct c_loc array checking for Fortran 2003 and Fortran 2008. 2013-04-04 Tobias Burnus <burnus@net-b.de> PR fortran/50269 * gfortran.dg/c_loc_test_21.f90: New. * gfortran.dg/c_loc_test_19.f90: Update dg-error. * gfortran.dg/c_loc_tests_10.f03: Update dg-error. * gfortran.dg/c_loc_tests_11.f03: Update dg-error. * gfortran.dg/c_loc_tests_4.f03: Update dg-error. * gfortran.dg/c_loc_tests_16.f90: Update dg-error. Added: trunk/gcc/testsuite/gfortran.dg/c_loc_test_21.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/check.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/c_loc_test_19.f90 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_10.f03 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_11.f03 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_16.f90 trunk/gcc/testsuite/gfortran.dg/c_loc_tests_4.f03
FIXED on the 4.9 trunk. I have now updated some constraint checks, hopefully, -std=f2003/f2008/f2008ts are now handled correctly. Missing is a check whether the argument is not contiguous. But that's tracked elsewhere. (Note: The standard does not demand simply contiguous but only contiguous arrays - thus, the compiler can only reject simple-to-detect noncontiguous arrays.)