There is a problem with character members of derived types when using polymorphic pointers, which triggers an ICE. It seems as if gfortran looses track of the length of `character` members when performing a downcast from a limited polymorphic type. The bug can be reproduced with this little code snippet: $ cat mo_compiler_test.f90 module foo TYPE, ABSTRACT :: t_Intermediate END TYPE t_Intermediate type, extends(t_Intermediate) :: t_Foo character(:), allocatable :: string end type t_Foo contains subroutine bar(me) class(t_Intermediate), target :: me select type(me) type is(t_Foo) print*, len(me%string) end select end subroutine bar end module foo $ gfortran -c -o mo_compiler_test.o mo_compiler_test.f90 f951: internal compiler error: in gfc_add_component_ref, at fortran/class.c:245 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. I have been able to reproduce this bug with gfortran versions 4.9.3, 5.1.0, 5.3.0, up to the current master in the git-svn mirror (commit a80f3f45b016). The bug is not present in versions up to 4.9.2. A git-bisect on the git-svn mirror revealed commit 53ec6b3f003a to be the first bad commit. It is interesting to note that this bug is not triggered when the `select type()` argument is an unlimited polymorphic pointer, even if that unlimited polymorphic pointer is just an alias for a limited polymorphic variable. See the comments in the attached code for details on this.
Created attachment 38357 [details] Code to reproduced the bug the forgotten attachment...
The change occurred between revisions r219823 (2015-01-18, compiles) and r219830 (2015-01-19, ICE), likely r219827 (pr60255) for gcc-5 and r221591 for gcc-4.9.
This is getting even nastier. As it turns out, even though the code I gave above compiles, it does not produce correct results. To be precise, if I use a routine like subroutine bar(me) class(t_Intermediate), pointer, intent(in) :: me class(*), pointer :: meAlias character(len = :), pointer :: textAlias meAlias => me select type(meAlias) type is(t_Foo) textAlias => meAlias%string print*, "'"//textAlias//"', len = ", len(textAlias) !OK print*, "'"//meAlias%string//"', len = ", len(meAlias%string) !string ok, len = nonsense end select end subroutine I get some completely wrong length in the second `print` statement (like `152660480`), even though the string itself is output correctly. Again, the indirection via an additional pointer produces correct results. Another curious fact is, that the large number is constant across objects within a single run, but different when I restart my program. So I'm willing to speculate that somehow the vtable pointer is mistaken for the string length, but that may be completely wrong.
ICE for both release and experimental : $ gfortran-6 pr70842.f90 f951: internal compiler error: in gfc_add_component_ref, at fortran/class.c:241 $ gfortran-7-20160710 pr70842.f90 f951: internal compiler error: in gfc_add_component_ref, at fortran/class.c:241 0x66ac54 gfc_add_component_ref(gfc_expr*, char const*) ../../gcc/fortran/class.c:241 0x66ad47 gfc_get_len_component(gfc_expr*) ../../gcc/fortran/class.c:585 0x694cb9 do_simplify ../../gcc/fortran/intrinsic.c:4150 0x69e60c gfc_intrinsic_func_interface(gfc_expr*, int) ../../gcc/fortran/intrinsic.c:4506 0x6e3e66 resolve_unknown_f ../../gcc/fortran/resolve.c:2718 0x6e3e66 resolve_function ../../gcc/fortran/resolve.c:3020 0x6e3e66 gfc_resolve_expr(gfc_expr*) ../../gcc/fortran/resolve.c:6353 0x6e8a91 gfc_resolve_code(gfc_code*, gfc_namespace*) ../../gcc/fortran/resolve.c:10469 0x6e87eb gfc_resolve_blocks(gfc_code*, gfc_namespace*) ../../gcc/fortran/resolve.c:9520 0x6e8b9e gfc_resolve_code(gfc_code*, gfc_namespace*) ../../gcc/fortran/resolve.c:10459 0x6eb272 resolve_codes ../../gcc/fortran/resolve.c:15667 0x6eb361 gfc_resolve(gfc_namespace*) ../../gcc/fortran/resolve.c:15701 0x6e9943 gfc_resolve(gfc_namespace*) ../../gcc/fortran/resolve.c:6236 0x6e9943 resolve_block_construct ../../gcc/fortran/resolve.c:9405 0x6e9943 gfc_resolve_code(gfc_code*, gfc_namespace*) ../../gcc/fortran/resolve.c:10682 0x6e87eb gfc_resolve_blocks(gfc_code*, gfc_namespace*) ../../gcc/fortran/resolve.c:9520 0x6f2c67 resolve_select_type ../../gcc/fortran/resolve.c:8625 0x6e9261 gfc_resolve_code(gfc_code*, gfc_namespace*) ../../gcc/fortran/resolve.c:10678 0x6eb272 resolve_codes ../../gcc/fortran/resolve.c:15667 0x6eb177 resolve_codes ../../gcc/fortran/resolve.c:15652
(In reply to Gerhard Steinmetz from comment #4) > ICE for both release and experimental : > > > $ gfortran-6 pr70842.f90 > f951: internal compiler error: in gfc_add_component_ref, at > fortran/class.c:241 > With the patch I posted earlier today and code in comment #1, I see gfc7 -c a.f90 a.f90:14:30: print*, len(me%string) 1 Error: Data transfer element at (1) cannot be polymorphic unless it is processed by a defined input/output procedure I don't use CLASS and know little about its expected behavior. Is the above even remotely right?
(In reply to kargl from comment #5) > With the patch I posted earlier today and code in comment #1, I see > > gfc7 -c a.f90 > a.f90:14:30: > > print*, len(me%string) > 1 > Error: Data transfer element at (1) cannot be polymorphic unless it > is processed by a defined input/output procedure > > I don't use CLASS and know little about its expected behavior. > Is the above even remotely right? I don't think so, but I may be wrong since I'm not an expert when it comes to the FORTRAN standard. The error sounds weird to me, because I would not consider `me%string` to be polymorphic to begin with, and because the value that is printed is the result of the `len()` intrinsic, which is just a non-polymorphic `integer`. Even the type of `me` is known precisely at this point since the statement appears within a `type is()` clause. What I would naively expect is that the code * compiles without error or warning (the issue in comment #1), and that it * prints the correct length of the string (the issue in comment #3). (I do hope my expectations are not in conflict with the standard...)
Hi Karl, (In reply to kargl from comment #5) > With the patch I posted earlier today and code in comment #1, I see which patch are you referring to? At least upto now I don't see a patch from you on the list or in this PR. > > gfc7 -c a.f90 > a.f90:14:30: > > print*, len(me%string) > 1 > Error: Data transfer element at (1) cannot be polymorphic unless it > is processed by a defined input/output procedure > > I don't use CLASS and know little about its expected behavior. > Is the above even remotely right? Not at all. That call to len() should map to me%.string giving the length of the string. (Note the dot in front of string; gfortran internal convention to store string length).
(In reply to vehre from comment #7) > Hi Karl, > > (In reply to kargl from comment #5) > > With the patch I posted earlier today and code in comment #1, I see > > which patch are you referring to? At least upto now I don't see a patch from > you on the list or in this PR. > See PR 71862
Patch available at: https://gcc.gnu.org/ml/fortran/2016-07/msg00063.html Waiting for review.
Author: vehre Date: Thu Jul 14 17:07:47 2016 New Revision: 238347 URL: https://gcc.gnu.org/viewcvs?rev=238347&root=gcc&view=rev Log: gcc/testsuite/ChangeLog: 2016-07-14 Andre Vehreschild <vehre@gcc.gnu.org> PR fortran/70842 * gfortran.dg/select_type_35.f03: New test. gcc/fortran/ChangeLog: 2016-07-14 Andre Vehreschild <vehre@gcc.gnu.org> PR fortran/70842 * simplify.c (gfc_simplify_len): Only for unlimited polymorphic types replace the expression's _data ref with a _len ref. Added: trunk/gcc/testsuite/gfortran.dg/select_type_35.f03 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/simplify.c trunk/gcc/testsuite/ChangeLog
Waiting one week for regression reports before applying to gcc-*-branches.
Author: vehre Date: Fri Jul 22 13:15:31 2016 New Revision: 238640 URL: https://gcc.gnu.org/viewcvs?rev=238640&root=gcc&view=rev Log: gcc/testsuite/ChangeLog: 2016-07-22 Andre Vehreschild <vehre@gcc.gnu.org> Backport from trunk: PR fortran/70842 * gfortran.dg/select_type_35.f03: New test. gcc/fortran/ChangeLog: 2016-07-22 Andre Vehreschild <vehre@gcc.gnu.org> Backport from trunk: PR fortran/70842 * simplify.c (gfc_simplify_len): Only for unlimited polymorphic types replace the expression's _data ref with a _len ref. Added: branches/gcc-6-branch/gcc/testsuite/gfortran.dg/select_type_35.f03 Modified: branches/gcc-6-branch/gcc/fortran/ChangeLog branches/gcc-6-branch/gcc/fortran/simplify.c branches/gcc-6-branch/gcc/testsuite/ChangeLog
Author: vehre Date: Fri Jul 22 14:12:59 2016 New Revision: 238644 URL: https://gcc.gnu.org/viewcvs?rev=238644&root=gcc&view=rev Log: gcc/testsuite/ChangeLog: 2016-07-22 Andre Vehreschild <vehre@gcc.gnu.org> Backport from trunk: PR fortran/70842 * gfortran.dg/select_type_35.f03: New test. gcc/fortran/ChangeLog: 2016-07-22 Andre Vehreschild <vehre@gcc.gnu.org> Backport from trunk: PR fortran/70842 * simplify.c (gfc_simplify_len): Only for unlimited polymorphic types replace the expression's _data ref with a _len ref. Added: branches/gcc-5-branch/gcc/testsuite/gfortran.dg/select_type_35.f03 Modified: branches/gcc-5-branch/gcc/fortran/ChangeLog branches/gcc-5-branch/gcc/fortran/simplify.c branches/gcc-5-branch/gcc/testsuite/ChangeLog
Author: vehre Date: Fri Jul 22 15:01:48 2016 New Revision: 238646 URL: https://gcc.gnu.org/viewcvs?rev=238646&root=gcc&view=rev Log: gcc/testsuite/ChangeLog: 2016-07-22 Andre Vehreschild <vehre@gcc.gnu.org> Backport from trunk: PR fortran/70842 * gfortran.dg/select_type_35.f03: New test. gcc/fortran/ChangeLog: 2016-07-22 Andre Vehreschild <vehre@gcc.gnu.org> Backport from trunk: PR fortran/70842 * simplify.c (gfc_simplify_len): Only for unlimited polymorphic types replace the expression's _data ref with a _len ref. Added: branches/gcc-4_9-branch/gcc/testsuite/gfortran.dg/select_type_35.f03 Modified: branches/gcc-4_9-branch/gcc/fortran/simplify.c branches/gcc-4_9-branch/gcc/testsuite/ChangeLog
Waiting one week for regressions before closing as fixed.
GCC 4.9 branch is being closed
> Waiting one week for regressions before closing as fixed. So closing.