Bug 38813 - ICE with C_LOC(array)
ICE with C_LOC(array)
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.4.0
: P3 normal
: ---
Assigned To: Not yet assigned to anyone
: diagnostic, ice-on-invalid-code, ice-on-valid-code, rejects-valid
Depends on:
Blocks: 32630
  Show dependency treegraph
 
Reported: 2009-01-12 13:13 UTC by Tobias Burnus
Modified: 2013-03-25 17:47 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-01-14 20:07:58


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2009-01-12 13:13:41 UTC
Found at http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/5392e4c270d4f3c7

The following program segfaults and valgrind shows:

==31102== Invalid read of size 4
==31102==    at 0x4B3E31: gfc_conv_function_call (trans-expr.c:2451)
==31102==    by 0x4B448A: gfc_conv_function_expr (trans-expr.c:3345)
==31102==    by 0x4B507C: gfc_trans_assignment_1 (trans-expr.c:4642)
==31102==    by 0x4B520C: gfc_trans_assignment (trans-expr.c:4804)
==31102==    by 0x49522F: gfc_trans_code (trans.c:1061)
==31102==    by 0x4ACC5A: gfc_generate_function_code (trans-decl.c:3849)
==31102==    by 0x46211B: gfc_parse_file (parse.c:3860)

I think NAG f95 is right by rejecting it with:
   Error: line 9: The argument to C_LOC must not be an array pointer
[and one needs to use as with C a pointer to the first element ("&target" or "&target[0]" not "&target[]" or something similar)].

It is accepted with ifort and g95.

Relevant trans-expr.c lines:

  2448                /* We should want it to do g77 calling convention.  */
  2449                f = (fsym != NULL)
  2450                  && !(fsym->attr.pointer || fsym->attr.allocatable)
  2451                  && fsym->as->type != AS_ASSUMED_SHAPE;
  2452                f = f || !sym->attr.always_explicit;


      use iso_c_binding
      implicit none
      type tY
         REAL (KIND=4), dimension(:),pointer :: y_fptr => NULL()
         Integer (Kind=4) :: ny                        = 0
      end type
      type(ty), target :: y_f
      type(c_ptr) :: y_cptr
      y_cptr = c_loc(y_f%y_fptr)
      end
Comment 1 Tobias Burnus 2009-01-12 13:34:35 UTC
> I think NAG f95 is right by rejecting it with:
>   Error: line 9: The argument to C_LOC must not be an array pointer

Or maybe not: "15.1.2.5 C_LOC(X)" has for the result value:

"(2) If X is an array data entity, the result is determined as if C_PTR were a derived type containing a scalar pointer component PX of the type and type parameters of X and the pointer assignment of CPTR%PX to the first element of X were executed"

The example is still wrong as it fails (1c):

"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"

Is seems as if
  a) no-pointer, no-allocatable arrays
  b) allocatable arrays (allocated without empty size)
are allowed. Thus the following programs should be valid -- and it also compiles with NAG f95:

      use iso_c_binding
      implicit none
      type tY
         REAL (KIND=c_float), dimension(5) :: y_fptr = 5
         REAL (KIND=c_float), dimension(:), allocatable :: y_fptr2
         Integer (Kind=c_int) :: ny                        = 0
      end type
      type(ty), target :: y_f
      type(c_ptr) :: y_cptr
      y_cptr = c_loc(y_f%y_fptr)
      allocate(y_f%y_fptr2(2))
      y_cptr = c_loc(y_f%y_fptr2)
      end
Comment 2 Tobias Burnus 2009-01-12 16:59:55 UTC
For the diagnostics: I think it works, but we are checking in case of C_LOC(Type%Comp)  the symbol Type instead of Comp. Assume that Type is a pointer and Comp is not then "gfc_is_data_pointer()" returns true for Type%Comp even though it is not a pointer (Type is a pointer, Type%Comp is the component of the target to which Type points). But somehow also the is_scalar_expr_ptr check and the args_sym->attr.dimension check point do something wrong.

For rejects valid: Make "Type" a pointer and Type%Comp an array.

The ICE itself is fixed by the following patch:

--- trans-expr.c        (Revision 143289)
+++ trans-expr.c
@@ -2451 +2451 @@ gfc_conv_function_call (gfc_se * se, gfc
-               && fsym->as->type != AS_ASSUMED_SHAPE;
+               && fsym->as && fsym->as->type != AS_ASSUMED_SHAPE;
Comment 3 Mikael Morin 2009-01-14 20:07:58 UTC
is_scalar_expr_ptr is weird.

Those are the things to change in it, IMHO:
 - is_scalar_expr_ptr does not need to check whether character lengths are equal to 1 as arbitrary length character variables are considered as scalars by the standard;
 - full arrays, (and array ranges as well) are non-scalar even if they are of size 1;
 - the whole reference chain should be checked, not only the last one. 

Hum, may be it could be reduced to a mere expr->rank == 0 ?
Comment 4 Tobias Burnus 2009-01-14 21:26:56 UTC
> @@ -2451 +2451 @@ gfc_conv_function_call (gfc_se * se, gfc
> -               && fsym->as->type != AS_ASSUMED_SHAPE;
> +               && fsym->as && fsym->as->type != AS_ASSUMED_SHAPE;

This might lead to wrong code (though I don't know what f77 means for C_LOC): I think that instead of fsym->as->type one needs to go through the refs to the component and do the check ...->as there.
Comment 5 Mikael Morin 2009-01-24 22:09:23 UTC
(In reply to comment #4)
> This might lead to wrong code (though I don't know what f77 means for C_LOC): I
> think that instead of fsym->as->type one needs to go through the refs to the
> component and do the check ...->as there.
> 
What about setting f to true unconditionally?
As C_LOC shall return a C-usable pointer, gfc_conv_array_parameter shall return a descriptorless array: we want to use the f77 calling convention anyway.
Comment 6 Salvatore Filippone 2012-01-13 12:44:46 UTC
Hello,
Has this ever been resolved? 
I still get an ICE with a code that is essentially that of comment 1, i.e. getting the C_LOC of an allocatable component; this is true of 4.6.1 and of current trunk as of today. 
Interestingly, the following compiles (but I have not tried yet if it works at runtime): 

module foo_mod
  type foo_type
    integer, allocatable :: idx(:)
  end type foo_type
end module foo_mod

subroutine bar2(data)
  use foo_mod
  use iso_c_binding 
  implicit none
  type(foo_type), intent(inout), target :: data 
  type(c_ptr)	      :: cptr
  
  call getcptr(cptr,data%idx)

contains
  subroutine getcptr(cp,v)
    type(c_ptr) :: cp
    integer, allocatable, target  :: v(:)
    cp = c_loc(v)
  end subroutine getcptr
end subroutine bar2


Thanks a lot
Salvatore
Comment 7 Salvatore Filippone 2012-01-13 12:48:13 UTC
(In reply to comment #6)
And the example that still fails:
--------------
module foo_mod
  type foo_type
    integer, allocatable :: idx(:)
  end type foo_type
end module foo_mod

subroutine bar(data)
  use foo_mod
  use iso_c_binding 
  implicit none
  type(foo_type), intent(inout), target :: data 
  type(c_ptr)	      :: cptr
  
  cptr = c_loc(data%idx)

end subroutine bar
------------------
[sfilippo@donald bug32]$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/gnu47/libexec/gcc/x86_64-unknown-linux-gnu/4.7.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc/configure --prefix=/usr/local/gnu47 --enable-languages=c,c++,fortran --with-gmp=/home/travel/GNUBUILD/gmp --with-mpfr=/home/travel/GNUBUILD/mpfr --with-mpc=/home/travel/GNUBUILD/mpc
Thread model: posix
gcc version 4.7.0 20120110 (experimental) (GCC) 
[sfilippo@donald bug32]$ gfortran -c bar.f90 
bar.f90: In function 'bar':
bar.f90:14:0: internal compiler error: Errore di segmentazione
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions
Comment 8 Tobias Burnus 2013-03-25 15:53:43 UTC
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
Comment 9 Tobias Burnus 2013-03-25 17:47:30 UTC
FIXED on the 4.9 trunk.