Bug 70842 - [5/6/7 Regression] internal compiler error with character members within a polymorphic pointer
Summary: [5/6/7 Regression] internal compiler error with character members within a po...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 5.1.0
: P4 normal
Target Milestone: 5.5
Assignee: Andre Vehreschild
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: 68241
  Show dependency treegraph
 
Reported: 2016-04-28 08:41 UTC by nathanael.huebbe
Modified: 2016-08-04 13:06 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work: 4.9.2
Known to fail: 4.9.3, 5.1.0, 5.3.0, 6.1.0, 7.0
Last reconfirmed: 2016-04-28 00:00:00


Attachments
Code to reproduced the bug (380 bytes, text/plain)
2016-04-28 08:43 UTC, nathanael.huebbe
Details

Note You need to log in before you can comment on or make changes to this bug.
Description nathanael.huebbe 2016-04-28 08:41:08 UTC
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.
Comment 1 nathanael.huebbe 2016-04-28 08:43:00 UTC
Created attachment 38357 [details]
Code to reproduced the bug

the forgotten attachment...
Comment 2 Dominique d'Humieres 2016-04-28 10:02:41 UTC
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.
Comment 3 nathanael.huebbe 2016-04-28 16:32:55 UTC
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.
Comment 4 Gerhard Steinmetz 2016-07-13 18:35:29 UTC
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
Comment 5 kargls 2016-07-13 21:51:28 UTC
(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?
Comment 6 nathanael.huebbe 2016-07-14 07:55:01 UTC
(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...)
Comment 7 Andre Vehreschild 2016-07-14 08:02:24 UTC
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).
Comment 8 kargls 2016-07-14 14:34:08 UTC
(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
Comment 9 Andre Vehreschild 2016-07-14 14:57:52 UTC
Patch available at:

https://gcc.gnu.org/ml/fortran/2016-07/msg00063.html

Waiting for review.
Comment 10 Andre Vehreschild 2016-07-14 17:08:19 UTC
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
Comment 11 Andre Vehreschild 2016-07-15 11:39:04 UTC
Waiting one week for regression reports before applying to gcc-*-branches.
Comment 12 Andre Vehreschild 2016-07-22 13:16:03 UTC
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
Comment 13 Andre Vehreschild 2016-07-22 14:13:33 UTC
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
Comment 14 Andre Vehreschild 2016-07-22 15:02:20 UTC
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
Comment 15 Andre Vehreschild 2016-07-22 15:04:35 UTC
Waiting one week for regressions before closing as fixed.
Comment 16 Richard Biener 2016-08-03 12:01:32 UTC
GCC 4.9 branch is being closed
Comment 17 Dominique d'Humieres 2016-08-04 13:06:04 UTC
> Waiting one week for regressions before closing as fixed.

So closing.