Bug 55037 - [4.8 Regression] [OOP] ICE with local allocatable variable of abstract type
Summary: [4.8 Regression] [OOP] ICE with local allocatable variable of abstract type
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-10-23 14:40 UTC by mrestelli
Modified: 2012-10-24 15:32 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-10-23 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description mrestelli 2012-10-23 14:40:31 UTC
The attached code (which should be correct) produces an I.C.E.

gfortran -c m.f90 -o m.o
m.f90: In function ‘sub’:
m.f90:27:0: internal compiler error: in gfc_conv_procedure_call, at
fortran/trans-expr.c:4218
    call u0%source(tmp)
     ^

gfortran --version
GNU Fortran (GCC) 4.8.0 20121023 (experimental)


module m1
 implicit none

 type, abstract :: c_stv
 contains
  procedure, pass(x) :: source
 end type c_stv

contains

 pure subroutine source(y,x)
  class(c_stv), intent(in)               :: x
  class(c_stv), allocatable, intent(out) :: y
 end subroutine source
end module m1

module m2
 use m1, only : c_stv
 implicit none

 contains

 ! Note: moving sub in m1 everything works.
 subroutine sub(u0)
  class(c_stv), intent(inout) :: u0
  class(c_stv), allocatable :: tmp
   call u0%source(tmp)
 end subroutine sub

end module m2
Comment 1 Dominique d'Humieres 2012-10-23 15:52:32 UTC
Confirmed. Revision 191494 (2012-09-19) is OK, revision 191799 (2012-09-27) is not. It seems likely a fallout of revision 191649 which introduced the assert

                          gcc_assert (fsym->ts.u.derived == e->ts.u.derived);
Comment 2 janus 2012-10-23 16:00:59 UTC
Confirmed. It works with 4.7.


Here is a variant which fails with a different ICE:

 implicit none
 type :: c_stv
 end type
 class(c_stv), allocatable :: tmp
 call source(tmp)
contains
 subroutine source(y)
  type(c_stv), allocatable, intent(out) :: y
 end subroutine
end



internal compiler error: Segmentation fault
  call source(tmp)
 ^
0xaacaa9 crash_signal
        /home/jweil/gcc48/trunk/gcc/toplev.c:335
0x5e601f contains_struct_check(tree_node*, tree_node_structure_enum, char const*, int, char const*)
        /home/jweil/gcc48/trunk/gcc/tree.h:3789
0x62e660 gfc_class_data_get(tree_node*)
        /home/jweil/gcc48/trunk/gcc/fortran/trans-expr.c:108
0x63a0a8 gfc_conv_procedure_call(gfc_se*, gfc_symbol*, gfc_actual_arglist*, gfc_expr*, vec_t<tree_node*>*)
        /home/jweil/gcc48/trunk/gcc/fortran/trans-expr.c:4203
Comment 3 janus 2012-10-24 09:45:59 UTC
(In reply to comment #1)
> It seems likely a fallout of revision 191649 which introduced the assert
> 
>                           gcc_assert (fsym->ts.u.derived == e->ts.u.derived);


Indeed I think removing this assert is sufficient for solving the problem in comment 0.

Since both the formal arg "y" as well as the expression being passed to it ("tmp") are polymorphic, the ts.u.derived points to the class container in both cases.

Now, the class container of "y" lives in m1, while that of "tmp" lives in m2 (apparently the "use, only" prevents it from being carried over). In principle this is not a big problem, we just should not assume they are equal ;)

If anything, we could assume that the types themselves (not the class containers) should be equal. But firstly, even this may not be strictly necessary (I'm not 100% sure right now), and secondly such conditions should have been checked by the present argument checking machinery.
Comment 4 janus 2012-10-24 10:25:49 UTC
(In reply to comment #2)
> Here is a variant which fails with a different ICE:

The problem with comment 2 is that 'gfc_class_data_get' is applied twice (in trans-expr.c, gfc_conv_procedure_call): Once in line 4188, and once in line 4203.

Here is a patch which fixes both comment 0 and comment 2 and is free of testsuite regressions:

Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(revision 192691)
+++ gcc/fortran/trans-expr.c	(working copy)
@@ -4180,13 +4180,6 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol *
 				     CLASS_DATA (fsym)->attr.class_pointer
 				     || CLASS_DATA (fsym)->attr.allocatable);
 
-		  if (fsym && (fsym->ts.type == BT_DERIVED
-			       || fsym->ts.type == BT_ASSUMED)
-		      && e->ts.type == BT_CLASS
-		      && !CLASS_DATA (e)->attr.dimension
-		      && !CLASS_DATA (e)->attr.codimension)
-		    parmse.expr = gfc_class_data_get (parmse.expr);
-
 		  /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 
 		     allocated on entry, it must be deallocated.  */
 		  if (fsym && fsym->attr.intent == INTENT_OUT
@@ -4215,7 +4208,6 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol *
 		      if (fsym->ts.type == BT_CLASS)
 			{
 			  gfc_symbol *vtab;
-			  gcc_assert (fsym->ts.u.derived == e->ts.u.derived);
 			  vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
 			  tmp = gfc_get_symbol_decl (vtab);
 			  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
@@ -4240,6 +4232,12 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol *
 
 		      gfc_add_expr_to_block (&se->pre, tmp);
 		    }
+		  else if (fsym && (fsym->ts.type == BT_DERIVED
+				    || fsym->ts.type == BT_ASSUMED)
+			   && e->ts.type == BT_CLASS
+			   && !CLASS_DATA (e)->attr.dimension
+			   && !CLASS_DATA (e)->attr.codimension)
+		    parmse.expr = gfc_class_data_get (parmse.expr);
 
 		  /* Wrap scalar variable in a descriptor. We need to convert
 		     the address of a pointer back to the pointer itself before,


Will commit as obvious ...
Comment 5 janus 2012-10-24 15:23:29 UTC
Author: janus
Date: Wed Oct 24 15:23:25 2012
New Revision: 192768

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=192768
Log:
2012-10-24  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/55037
	* trans-expr.c (gfc_conv_procedure_call): Move a piece of code and
	remove an assert.

2012-10-24  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/55037
	* gfortran.dg/class_dummy_4.f03: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/class_dummy_4.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 6 janus 2012-10-24 15:32:42 UTC
Both ICEs reported in this PR should be fixed by r192768.

[Note that this commit does not literally contain the patch from comment 4, but strictly moves the IF clause, instead of making it an ELSE IF.]

Thanks for the report. Closing.