Bug 47463 - [OOP] ICE in gfc_add_component_ref
Summary: [OOP] ICE in gfc_add_component_ref
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: 4.6.0
Assignee: janus
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2011-01-25 18:58 UTC by Rich Townsend
Modified: 2016-11-16 13:48 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-01-31 10:29:20


Attachments
Tar file containing source code and Makefile (5.71 KB, application/x-tar)
2011-01-25 18:58 UTC, Rich Townsend
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rich Townsend 2011-01-25 18:58:32 UTC
Created attachment 23124 [details]
Tar file containing source code and Makefile

Compiling the attached code (Makefile included) results in the following internal compiler error:

gfortran-mp-4.6  -std=f2003   -c hydro_flow.f90
f951: internal compiler error: in gfc_add_component_ref, at fortran/class.c:79
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
make: *** [hydro_flow.mod] Error 1

The code is a stripped-down version of a new F2003 hydrodynamics code; it's v. important that I get it up and running as soon as possible.

Thanks,

Rich
Comment 1 Tobias Burnus 2011-01-25 19:53:04 UTC
4.5 fails with:
  use hydro_recon
                 1
Internal Error at (1):
mio_component_ref(): Component not found

Thus, it is not a regression.

 * * *

Compiling with Crayftn 7.2.4 shows the error:

    call this%init(st, gr)
             ^             
ftn-389 crayftn: ERROR INIT_PARAMS, File = hydro_flow.f90, Line = 55, Column = 14 
  No specific match can be found for the generic subprogram call "INIT".

 * * *

Regarding GCC 4.6:

The ICE occurs in gfc_add_component_ref for e being the EXPR_FUNCTION "this->_vptr" where "_vptr" is e->ref->u.c.component->name and e->ref->next == NULL. Also  e->value.function == {actual = 0x0, name = 0x0, isym = 0x0, esym = 0x0}.

The caller is resolve_typebound_subroutine where code->op == EXEC_ASSIGN_CALL; the call is:
   gfc_add_component_ref (code->expr1, name);
with "name" == assign and the expression as shown above.

Somewhat reduced test case:

module hydro_state
  type :: state_t
   contains
     procedure :: assign
     generic   :: assignment(=) => assign
  end type state_t
contains
  subroutine assign (this, that)
    class(state_t), intent(inout) :: this
    class(state_t), intent(in)    :: that
  end subroutine assign
end module hydro_state

module hydro_flow
  use hydro_state
  type :: flow_t
     class(state_t), allocatable :: st
  end type flow_t
contains
  subroutine init_comps (this, st)
    class(flow_t), intent(out) :: this
    class(state_t), intent(in) :: st

    allocate(state_t :: this%st)
    this%st = st
  end subroutine init_comps
end module hydro_flow
Comment 2 Mikael Morin 2011-01-25 20:14:40 UTC
(In reply to comment #1)
> 4.5 fails with:
>   use hydro_recon
>                  1
> Internal Error at (1):
> mio_component_ref(): Component not found
> 
This is PR 45827

> 
> Regarding GCC 4.6:
> 
There have been several PRs like this.
For example PR 45933.
Comment 3 Rich Townsend 2011-01-27 04:06:10 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > 4.5 fails with:
> >   use hydro_recon
> >                  1
> > Internal Error at (1):
> > mio_component_ref(): Component not found
> > 
> This is PR 45827
> 

This bug apparently persists in 4.6; I'm experiencing it with a different piece of code. It seems likely that memory corruption is the issue, since I can get the bug to appear/disappear by removing unrelated code segments. Reporting this sort of bug is very difficult, since its manifestation is so platform-specific. Any suggestions?

cheers,

Rich
Comment 4 janus 2011-01-30 14:31:14 UTC
Slightly reduced/modified test case:

module hydro_state
  type :: state_t
   contains
     procedure :: assign
     generic   :: assignment(=) => assign
  end type
contains
  subroutine assign (this, that)
    class(state_t), intent(inout) :: this
    class(state_t), intent(in)    :: that
  end subroutine
end module


  use hydro_state
  type :: flow_t
     type(state_t) :: st
  end type

  class(flow_t),pointer :: this
  type(state_t) :: st
  this%st = st

end
Comment 5 janus 2011-01-31 10:29:20 UTC
Alright, here is a draft patch:


Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 169407)
+++ gcc/fortran/resolve.c	(working copy)
@@ -5877,14 +5877,12 @@ resolve_typebound_subroutine (gfc_code *code)
 
   /* Deal with typebound operators for CLASS objects.  */
   expr = code->expr1->value.compcall.base_object;
-  if (expr && expr->symtree->n.sym->ts.type == BT_CLASS
-	&& code->expr1->value.compcall.name)
+  if (expr && expr->ts.type == BT_CLASS && code->expr1->value.compcall.name)
     {
       /* Since the typebound operators are generic, we have to ensure
 	 that any delays in resolution are corrected and that the vtab
 	 is present.  */
-      ts = expr->symtree->n.sym->ts;
-      declared = ts.u.derived;
+      declared = expr->ts.u.derived;
       c = gfc_find_component (declared, "_vptr", true, true);
       if (c->ts.u.derived == NULL)
 	c->ts.u.derived = gfc_find_derived_vtab (declared);
@@ -5895,6 +5893,7 @@ resolve_typebound_subroutine (gfc_code *code)
       /* Use the generic name if it is there.  */
       name = name ? name : code->expr1->value.function.esym->name;
       code->expr1->symtree = expr->symtree;
+      code->expr1->ref = gfc_copy_ref (expr->ref);
       expr->symtree->n.sym->ts.u.derived = declared;
       gfc_add_vptr_component (code->expr1);
       gfc_add_component_ref (code->expr1, name);



This fixes comment #1 and comment #4. For the original test case I now get:

gfortran-4.6  -std=f2003   -c hydro_types.f90
gfortran-4.6  -std=f2003   -c hydro_state.f90
gfortran-4.6  -std=f2003   -c hydro_speeds.f90
gfortran-4.6  -std=f2003   -c hydro_grid.f90
gfortran-4.6  -std=f2003   -c hydro_flow.f90
hydro_flow.f90:55.13:

    call this%init(st, gr)
             1
Error: Found no matching specific binding for the call to the GENERIC 'init' at (1)



Changing this generic call to the corresponding specific type-bound procedure, I get:

gfortran-4.6  -std=f2003   -c hydro_flow.f90
hydro_flow.f90:55.13:

    call this%init_comps(st, gr)
             1
Error: Type mismatch in argument 'this' at (1); passed CLASS(flow_t) to CLASS(grid_t)



And the same without type-binding:

gfortran-4.6  -std=f2003   -c hydro_flow.f90
hydro_flow.f90:55.20:

    call init_comps(this, st, gr)
                    1
Error: Type mismatch in argument 'this' at (1); passed CLASS(flow_t) to CLASS(grid_t)



The code does look valid to me (unless I'm missing something), so this seems to be another gfortran bug.
Comment 6 Tobias Burnus 2011-01-31 11:03:31 UTC
(In reply to comment #5)
> hydro_flow.f90:55.13:
>     call this%init(st, gr)
>              1
> Error: Found no matching specific binding for the call to the GENERIC
> 'init' at (1)

That matches Cray's ftn (cf. comment 1):
    call this%init(st, gr)
             ^             
ftn-389 crayftn: ERROR INIT_PARAMS, File = hydro_flow.f90, Line = 55, Column =
14 
  No specific match can be found for the generic subprogram call "INIT".



> Changing this generic call to the corresponding specific type-bound procedure,

I assume s/this%init/this%init_comps/ in that line. With Crayftn I then get the following, which looks at a glance like a bug in crayftn, though I have not checked it:

     procedure :: init_comps
                  ^
ftn-1130 crayftn: ERROR HYDRO_FLOW, File = hydro_flow.f90, Line = 21, Column = 19
  "INIT_COMPS" is specified as a procedure-name in a type bound procedure statement.  It must be a module procedure or an external procedure with an explicit interface.

  subroutine init_comps (this, st, gr)
             ^
ftn-575 crayftn: ERROR HYDRO_FLOW, File = hydro_flow.f90, Line = 66, Column = 14
  "INIT_COMPS" has been used as a subroutine, therefore it must not be declared as a module procedure subroutine.


> I get:
[ Some gfortran error message, completely different from Crays]


> And the same without type-binding:
>     call init_comps(this, st, gr)
> Error: Type mismatch in argument 'this' at (1); passed CLASS(flow_t) to
> CLASS(grid_t)

That version works with Crayftn. It then compiles hydro_flow.f90 - and stops in hydro_recon.f90 (line 31) for "fl%n" as '"N" is not a component of derived type "FLOW_T"'
Comment 7 janus 2011-01-31 14:49:00 UTC
(In reply to comment #5)
> Alright, here is a draft patch:

The patch in comment #5 regtests cleanly. I will commit as obvious soon ...
Comment 8 janus 2011-01-31 18:11:36 UTC
Author: janus
Date: Mon Jan 31 18:11:32 2011
New Revision: 169443

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169443
Log:
2011-01-31  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/47463
	* resolve.c (resolve_typebound_subroutine): Bug fix for the case of
	an argument of a typebound assignment being a component.


2011-01-31  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/47463
	* gfortran.dg/typebound_assignment_1.f03: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/typebound_assignment_1.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog
Comment 9 Tobias Burnus 2011-01-31 21:42:29 UTC
(In reply to comment #6)
> > And the same without type-binding:
> >     call init_comps(this, st, gr)
> > Error: Type mismatch in argument 'this' at (1); passed CLASS(flow_t) to
> > CLASS(grid_t)

I looked closer at that version.

a)  It works if one reverses the order of subroutines (all versions)

Rich: That's a work around, which is sufficient to compile the whole program. Note: You need a gfortran, which includes Janus' patch from comment 8.


b) For the failing version. The formal argument in compare_actual_formal alias compare_parameter is odd:

(gdb) p a->expr->ts.u.derived->name
$17 = 0x2aaaacf0eae0 "__class_hydro_flow_Flow_t"
(gdb) p f->sym->ts.u.derived->name
$18 = 0x2aaaacf0eac0 "__class_hydro_grid_Grid_t_a"
(gdb) p f->sym->name
$19 = 0x2aaaace40fb0 "this"

Namely, the formal argument has the right name, but it is associated with the wrong typespec!

 * * *

Reduced test case:

module hydro_grid
  type :: grid_t
   contains
     procedure :: assign
     generic   :: assignment(=) => assign
  end type grid_t
  public :: grid_t
contains
  subroutine assign (this, that)
    class(grid_t), intent(inout) :: this
    class(grid_t), intent(in)    :: that
  end subroutine assign
end module hydro_grid

module hydro_flow
  use hydro_grid
  type :: flow_t
     class(grid_t), allocatable  :: gr     ! Computation grid
  end type flow_t
contains
  subroutine init_params (this)
    class(flow_t), intent(out) :: this
    type(grid_t)               :: gr
   call init_comps(this, gr)
  end subroutine init_params
  subroutine init_comps (this, gr)
    class(flow_t), intent(out) :: this
    class(grid_t), intent(in)  :: gr
    this%gr = gr
  end subroutine init_comps
end module hydro_flow
Comment 10 Diego Novillo 2011-02-02 18:12:05 UTC
Author: dnovillo
Date: Wed Feb  2 18:11:56 2011
New Revision: 169722

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169722
Log:
2011-01-31  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/47463
	* resolve.c (resolve_typebound_subroutine): Bug fix for the case of
	an argument of a typebound assignment being a component.


2011-01-31  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/47463
	* gfortran.dg/typebound_assignment_1.f03: New.

Added:
    branches/google/integration/gcc/testsuite/gfortran.dg/typebound_assignment_1.f03
Modified:
    branches/google/integration/gcc/fortran/ChangeLog
    branches/google/integration/gcc/fortran/resolve.c
    branches/google/integration/gcc/testsuite/ChangeLog
Comment 11 janus 2011-02-09 18:08:45 UTC
The strange behavior of the test case in comment #9 can be cured by just removing one peculiar line of code:

Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 169977)
+++ gcc/fortran/resolve.c	(working copy)
@@ -5894,7 +5894,6 @@ resolve_typebound_subroutine (gfc_code *code)
       name = name ? name : code->expr1->value.function.esym->name;
       code->expr1->symtree = expr->symtree;
       code->expr1->ref = gfc_copy_ref (expr->ref);
-      expr->symtree->n.sym->ts.u.derived = declared;
       gfc_add_vptr_component (code->expr1);
       gfc_add_component_ref (code->expr1, name);
       code->expr1->value.function.esym = NULL;


This line seems completely bogus to me. I have no idea what it's supposed to do. In any case it came from the following commit:

http://gcc.gnu.org/viewcvs/trunk/gcc/fortran/resolve.c?r1=162313&r2=162312&pathrev=162313
Comment 12 Tobias Burnus 2011-02-09 18:52:10 UTC
(In reply to comment #11)
> This line seems completely bogus to me. I have no idea what it's supposed to
> do. In any case it came from the following commit:

Cf. PR 42385 / http://gcc.gnu.org/viewcvs?view=revision&revision=162313
which was committed by Paul.

I do not see whether the line makes sense or not. The idea seems to be to fix not fully resolved TBP -- but it is not completely clear to me whether that is ever needed in such a way. As the test case [cf. comment 9 (b)] shows, the current way is definitely wrong.
Comment 13 janus 2011-02-09 20:18:31 UTC
(In reply to comment #12)
> I do not see whether the line makes sense or not. The idea seems to be to fix
> not fully resolved TBP -- but it is not completely clear to me whether that is
> ever needed in such a way.

Apparently it's not needed, since removing the line does not introduce any regressions in the testsuite. Perhaps it was making up for another bug which is fixed by now.

I am going to commit the patch in comment #11 as obvious ...
Comment 14 janus 2011-02-09 20:30:23 UTC
Author: janus
Date: Wed Feb  9 20:30:20 2011
New Revision: 169985

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169985
Log:
2011-02-09  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/47463
	* resolve.c (resolve_typebound_subroutine): Remove erroneous line.


2011-02-09  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/47463
	* gfortran.dg/typebound_assignment_2.f03: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/typebound_assignment_2.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog
Comment 15 janus 2011-02-09 20:37:04 UTC
I think r169985 should fix all remaining problems in this PR. The original test case now gives me:

gfortran-4.6  -std=f2003   -c hydro_types.f90
gfortran-4.6  -std=f2003   -c hydro_state.f90
gfortran-4.6  -std=f2003   -c hydro_speeds.f90
gfortran-4.6  -std=f2003   -c hydro_grid.f90
gfortran-4.6  -std=f2003   -c hydro_flow.f90
gfortran-4.6  -std=f2003   -c hydro_recon.f90
gfortran-4.6  -std=f2003   -c hydro_evolve.f90
hydro_evolve.f90:10.18:

  use hydro_fluxes
                  1
Fatal Error: Can't open module file 'hydro_fluxes.mod' for reading at (1): No such file or directory


Closing as fixed.
Comment 16 Tobias Burnus 2011-02-09 21:06:05 UTC
(In reply to comment #13)
> I am going to commit the patch in comment #11 as obvious ...

Can you CC the patch to gcc-patches@ & fortran@?
Comment 17 paul.richard.thomas@gmail.com 2011-02-10 05:24:24 UTC
Dear Janus,

> Apparently it's not needed, since removing the line does not introduce any
> regressions in the testsuite. Perhaps it was making up for another bug which is
> fixed by now.
>

I have no memory of what that was about, at all :-(

Thanks for fixing it.

Paul