Bug 59450 - [OOP] ICE for type-bound-procedure expression in module procedure interface
Summary: [OOP] ICE for type-bound-procedure expression in module procedure interface
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.8.2
: P3 normal
Target Milestone: 4.9.0
Assignee: janus
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2013-12-10 14:33 UTC by bugs
Modified: 2016-11-16 15:49 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-12-10 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description bugs 2013-12-10 14:33:09 UTC
Hi,

when I try to compile the code below I receive an internal compiler error. The idea of the test case is to have a base class with a type-bound procedure returning an array. The size of the array is determined by using a specification function with deferred binding, i.e. it will be implemented in a child class / extended derived type.

When I use a component of the base class instead of the specification function the code compiles without problems.

module classes

  implicit none

  type, abstract :: base_class
     integer :: varnum
   contains
     procedure(pvf_get_num), nopass, deferred :: get_num
     procedure :: get_array
  end type base_class

  abstract interface
     pure function pvf_get_num() result(num)
       integer :: num
     end function pvf_get_num
  end interface

contains

  function get_array( this ) result(array)
    class(base_class), intent(in) :: this

    ! compiles
    ! integer, dimension( this%varnum ) :: array

    ! crashes
    integer, dimension( this%get_num() ) :: array

    array = 0
    array(1) = 1
  end function get_array

end module classes

In detail I obtain the following

Driving: gfortran -v --save-temps gcc-test2.f90 -l gfortran -l m -shared-libgcc
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/lrz/mnt/sys.x86_64/compilers/gcc/4.8.2/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.8.2/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.8.2/configure --prefix=/lrz/sys/compilers/gcc/4.8.2 --enable-languages=ada,c,c++,fortran,java,go,objc,obj-c++ --with-mpfr=/lrz/sys/libraries/mpfr/3.0.0 --with-gmp=/lrz/sys/libraries/gmp/5.0.1 --with-mpc=/lrz/sys/libraries/mpc/0.9
Thread model: posix
gcc version 4.8.2 (GCC) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /lrz/mnt/sys.x86_64/compilers/gcc/4.8.2/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.8.2/f951 gcc-test2.f90 -quiet -dumpbase gcc-test2.f90 -mtune=generic -march=x86-64 -auxbase gcc-test2 -version -fintrinsic-modules-path /lrz/mnt/sys.x86_64/compilers/gcc/4.8.2/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.2/finclude -o gcc-test2.s
GNU Fortran (GCC) version 4.8.2 (x86_64-unknown-linux-gnu)
        compiled by GNU C version 4.8.2, GMP version 5.0.1, MPFR version 3.0.0, MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU Fortran (GCC) version 4.8.2 (x86_64-unknown-linux-gnu)
        compiled by GNU C version 4.8.2, GMP version 5.0.1, MPFR version 3.0.0, MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
f951: internal compiler error: Segmentation fault
0x87f55f crash_signal
        ../../gcc-4.8.2/gcc/toplev.c:332
0x55971e mio_expr
        ../../gcc-4.8.2/gcc/fortran/module.c:3300
0x559d68 mio_array_spec
        ../../gcc-4.8.2/gcc/fortran/module.c:2406
0x559e8f mio_component
        ../../gcc-4.8.2/gcc/fortran/module.c:2596
0x55a11a mio_component_list
        ../../gcc-4.8.2/gcc/fortran/module.c:2624
0x55a11a mio_symbol
        ../../gcc-4.8.2/gcc/fortran/module.c:3816
0x55a442 write_symbol
        ../../gcc-4.8.2/gcc/fortran/module.c:5090
0x55a58d write_symbol0
        ../../gcc-4.8.2/gcc/fortran/module.c:5130
0x55a535 write_symbol0
        ../../gcc-4.8.2/gcc/fortran/module.c:5109
0x55a535 write_symbol0
        ../../gcc-4.8.2/gcc/fortran/module.c:5109
0x55a535 write_symbol0
        ../../gcc-4.8.2/gcc/fortran/module.c:5109
0x55caa7 write_module
        ../../gcc-4.8.2/gcc/fortran/module.c:5396
0x55caa7 gfc_dump_module(char const*, int)
        ../../gcc-4.8.2/gcc/fortran/module.c:5534
0x56844a gfc_parse_file()
        ../../gcc-4.8.2/gcc/fortran/parse.c:4623
0x5a3c05 gfc_be_parse_file
        ../../gcc-4.8.2/gcc/fortran/f95-lang.c:189
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.

Compiling the same source with 4.7.1 (on another system) I do not receive an ICE, but instead get error reports that the specification functions wouldn't be pure

Using built-in specs.
COLLECT_GCC=gfortran-4.7.1
Target: x86_64-unknown-linux-gnu
Configured with: ./configure --prefix /home/SOFTWARE/GCC/gcc-4.7.1 --program-suffix=-4.7.1 --enable-version-specific-runtime-libs --enable-languages=c,c++,fortran
Thread model: posix
gcc version 4.7.1 (GCC) 
COLLECT_GCC_OPTIONS='-v' '-c' '-save-temps' '-mtune=generic' '-march=x86-64'
 /home/SOFTWARE/GCC/gcc-4.7.1/libexec/gcc/x86_64-unknown-linux-gnu/4.7.1/f951 gcc-test2.f90 -quiet -dumpbase gcc-test2.f90 -mtune=generic -march=x86-64 -auxbase gcc-test2 -version -fintrinsic-modules-path /home/SOFTWARE/GCC/gcc-4.7.1/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/finclude -o gcc-test2.s
GNU Fortran (GCC) version 4.7.1 (x86_64-unknown-linux-gnu)
        compiled by GNU C version 4.7.1, GMP version 4.3.2, MPFR version 3.0.0-p3, MPC version 0.8.2
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU Fortran (GCC) version 4.7.1 (x86_64-unknown-linux-gnu)
        compiled by GNU C version 4.7.1, GMP version 4.3.2, MPFR version 3.0.0-p3, MPC version 0.8.2
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
gcc-test2.f90:27.23:

    integer, dimension( this%get_num() ) :: array
                       1
Error: Function 'this' at (1) must be PURE
gcc-test2.f90:27.23:

    integer, dimension( this%get_num() ) :: array
                       1
Error: Function 'this' at (1) must be PURE
gcc-test2.f90:27.23:

    integer, dimension( this%get_num() ) :: array
                       1
Error: Function 'this' at (1) must be PURE
gcc-test2.f90:27.23:

    integer, dimension( this%get_num() ) :: array
                       1
Error: Function 'this' at (1) must be PURE
gcc-test2.f90:27.23:

    integer, dimension( this%get_num() ) :: array
                       1
Error: Function 'this' at (1) must be PURE
gcc-test2.f90:27.23:

    integer, dimension( this%get_num() ) :: array
                       1
Error: Function 'this' at (1) must be PURE
gcc-test2.f90:27.23:

    integer, dimension( this%get_num() ) :: array
                       1
Error: Function 'this' at (1) must be PURE
gcc-test2.f90:27.23:

    integer, dimension( this%get_num() ) :: array
                       1
Error: Function 'this' at (1) must be PURE
gcc-test2.f90:27.23:

    integer, dimension( this%get_num() ) :: array
                       1
Error: Function 'this' at (1) must be PURE

Tanks in advance
Marcus
Comment 1 janus 2013-12-10 15:44:09 UTC
Confirmed. Thanks for the bug report.

Here is a variant with a non-abstract class which shows the same ICE (with every version I tried - from 4.6 to trunk):


module classes

  implicit none

  type :: base_class
   contains
     procedure, nopass :: get_num
  end type

contains

  pure integer function get_num()
  end function

  function get_array( this ) result(array)
    class(base_class), intent(in) :: this
    integer, dimension( this%get_num() ) :: array
  end function

end module
Comment 2 janus 2013-12-10 16:06:27 UTC
Draft patch which fixes the error (not regtested):


Index: gcc/fortran/module.c
===================================================================
--- gcc/fortran/module.c	(revision 205857)
+++ gcc/fortran/module.c	(working copy)
@@ -3358,12 +3358,24 @@ mio_expr (gfc_expr **ep)
 	{
 	  e->value.function.name
 	    = mio_allocated_string (e->value.function.name);
-	  flag = e->value.function.esym != NULL;
+	  if (e->value.function.esym)
+	    flag = 1;
+	  else if (e->ref)
+	    flag = 2;
+	  else
+	    flag = 0;
 	  mio_integer (&flag);
-	  if (flag)
-	    mio_symbol_ref (&e->value.function.esym);
-	  else
-	    write_atom (ATOM_STRING, e->value.function.isym->name);
+	  switch (flag)
+	    {
+	    case 1:
+	      mio_symbol_ref (&e->value.function.esym);
+	      break;
+	    case 2:
+	      mio_ref_list (&e->ref);
+	      break;
+	    default:
+	      write_atom (ATOM_STRING, e->value.function.isym->name);
+	    }
 	}
       else
 	{
@@ -3372,10 +3384,15 @@ mio_expr (gfc_expr **ep)
 	  free (atom_string);
 
 	  mio_integer (&flag);
-	  if (flag)
-	    mio_symbol_ref (&e->value.function.esym);
-	  else
+	  switch (flag)
 	    {
+	    case 1:
+	      mio_symbol_ref (&e->value.function.esym);
+	      break;
+	    case 2:
+	      mio_ref_list (&e->ref);
+	      break;
+	    default:
 	      require_atom (ATOM_STRING);
 	      e->value.function.isym = gfc_find_function (atom_string);
 	      free (atom_string);
Comment 3 janus 2013-12-10 16:18:04 UTC
Additional problem (unrelated to the ICE): Removing 'pure' in comment 1 yields the error:

    integer, dimension( this%get_num() ) :: array
                       1
Error: Function 'this' at (1) must be PURE


An error about missing pureness is correct in principle, but there are two problems with this:
1) The function name in the error message is wrong: There is no function named 'this'.
2) The error appears twice.
Comment 4 janus 2013-12-10 18:53:12 UTC
(In reply to janus from comment #2)
> Draft patch which fixes the error (not regtested):

Does regtest cleanly.
Comment 5 bugs 2013-12-13 08:33:47 UTC
(In reply to janus from comment #4)
> (In reply to janus from comment #2)
> > Draft patch which fixes the error (not regtested):
> 
> Does regtest cleanly.

Hi,

just wanted to say thanks. Your speed is terrific :)

Cheers
Marcus
Comment 6 janus 2013-12-14 10:31:58 UTC
Author: janus
Date: Sat Dec 14 10:31:56 2013
New Revision: 205983

URL: http://gcc.gnu.org/viewcvs?rev=205983&root=gcc&view=rev
Log:
2013-12-14  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/59450
	* module.c (mio_expr): Handle type-bound function expressions.


2013-12-14  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/59450
	* gfortran.dg/typebound_proc_31.f90: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/typebound_proc_31.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/module.c
    trunk/gcc/testsuite/ChangeLog
Comment 7 janus 2013-12-14 10:47:06 UTC
(In reply to bugs from comment #5)
> just wanted to say thanks. Your speed is terrific :)

you're welcome :)

The fix has landed on trunk by now. If the example you posted is part of a larger code base, it would be great if you could test the full code with a current gfortran trunk build. In case your code is publicly available, I can also test it for you.
Comment 8 janus 2013-12-14 18:01:29 UTC
(In reply to janus from comment #7)
> The fix has landed on trunk by now.

... therefore I'm closing this PR.

Feel free to post any follow-up comments here, or open a new PR in case of further problems.
Comment 9 bugs 2013-12-18 15:16:28 UTC
Hi,

verified that the ICE is gone in gcc version 4.9.0 20131217 (experimental). Thanks a lot. However, there is still a problem. As it is no longer an ICE I filed a new bug 59547 

Cheers
Marcus