Bug 43227 - [4.5 Regression] ICE: segmentation fault in mio_expr
Summary: [4.5 Regression] ICE: segmentation fault in mio_expr
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: fortran-dev
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2010-03-02 09:44 UTC by Dominique d'Humieres
Modified: 2010-04-24 12:30 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-04-18 11:09:35


Attachments
Fix for the problem (347 bytes, patch)
2010-04-18 17:33 UTC, Paul Thomas
Details | Diff
A provisional fix for the PR (736 bytes, patch)
2010-04-19 21:16 UTC, Paul Thomas
Details | Diff
fix for this PR and PR43266 (1.89 KB, patch)
2010-04-20 06:19 UTC, Paul Thomas
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dominique d'Humieres 2010-03-02 09:44:53 UTC
Compiling the original test for pr43199 with fortran-dev revision 157148 gives a segmentation fault:

(gdb) run pr43199.f90
Starting program: /opt/gcc/gcc4.5d/libexec/gcc/x86_64-apple-darwin10/4.5.0/f951 pr43199.f90
Reading symbols for shared libraries .++++++++++++..... done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x000000010005a6a5 in mio_expr (ep=<value temporarily unavailable, due to optimizations>) at ../../for_work/gcc/fortran/module.c:3074
3074		    write_atom (ATOM_STRING, e->value.function.isym->name);
(gdb) bt
#0  0x000000010005a6a5 in mio_expr (ep=<value temporarily unavailable, due to optimizations>) at ../../for_work/gcc/fortran/module.c:3074
#1  0x000000010005ac8d in mio_charlen (clp=0x1418425f0) at ../../for_work/gcc/fortran/module.c:2050
#2  0x000000010005a4df in mio_typespec (ts=0x1418425e8) at ../../for_work/gcc/fortran/module.c:2106
#3  0x000000010005b377 in mio_component (c=0x1418425e0) at ../../for_work/gcc/fortran/module.c:2343
#4  0x000000010005b578 in mio_symbol (sym=0x141841880) at ../../for_work/gcc/fortran/module.c:2393
#5  0x000000010005b9ed in write_symbol (n=4, sym=0x141841880) at ../../for_work/gcc/fortran/module.c:4787
#6  0x000000010005ba9f in write_symbol1 (p=0x1418b4570) at ../../for_work/gcc/fortran/module.c:4856
#7  0x000000010005ba65 in write_symbol1 (p=0x1418b1990) at ../../for_work/gcc/fortran/module.c:4860
#8  0x000000010005ba53 in write_symbol1 (p=0x1418b1bd0) at ../../for_work/gcc/fortran/module.c:4851
#9  0x000000010005ba53 in write_symbol1 (p=0x1418b25f0) at ../../for_work/gcc/fortran/module.c:4851
#10 0x000000010005ba65 in write_symbol1 (p=0x1418acad0) at ../../for_work/gcc/fortran/module.c:4860
#11 0x000000010005ba53 in write_symbol1 (p=0x1418b3a30) at ../../for_work/gcc/fortran/module.c:4851
#12 0x000000010005ba65 in write_symbol1 (p=0x1418ac890) at ../../for_work/gcc/fortran/module.c:4860
#13 0x000000010005ba65 in write_symbol1 (p=0x1418ac650) at ../../for_work/gcc/fortran/module.c:4860
#14 0x000000010005ba53 in write_symbol1 (p=0x1418b3c70) at ../../for_work/gcc/fortran/module.c:4851
#15 0x000000010005ba65 in write_symbol1 (p=0x1418ab9f0) at ../../for_work/gcc/fortran/module.c:4860
#16 0x000000010005ba53 in write_symbol1 (p=0x1418b1510) at ../../for_work/gcc/fortran/module.c:4851
#17 0x000000010005d6dc in gfc_dump_module (name=0x7fff5fbfd3dd "", dump_flag=<value temporarily unavailable, due to optimizations>) at ../../for_work/gcc/fortran/module.c:5006
#18 0x0000000100069b5b in gfc_parse_file () at ../../for_work/gcc/fortran/parse.c:4226
#19 0x00000001000a2f4c in gfc_be_parse_file (set_yydebug=<value temporarily unavailable, due to optimizations>) at ../../for_work/gcc/fortran/f95-lang.c:239
#20 0x00000001006d61ea in toplev_main (argc=2, argv=0x7fff5fbfd968) at ../../for_work/gcc/toplev.c:1053
#21 0x00000001000017f4 in start ()

Note that this pr may be related to or a duplicate of pr42274. Since the exact places of the segmentation fault are different, I prefer to open a new pr. If this pr is a duplicate, please feel free to close it.
Comment 1 janus 2010-04-15 21:30:16 UTC
Here is a reduced test case, which ICEs with the same backtrace:


module m_string

  type t_string
    character, dimension(:), allocatable :: string
  contains
    procedure :: char => string_to_char
  end type t_string

contains

  function string_to_char (s) result(res)
    class(t_string), intent(in) :: s
    character(len=size(s%string)) :: res
  end function string_to_char

end module m_string
Comment 2 paul.richard.thomas@gmail.com 2010-04-16 07:36:46 UTC
Subject: Re:  [fortran-dev Regression] ICE: segmentation 
	fault in mio_expr

Janus,

I am looking at this and PR42274; I will be in a hotel room the
evenings of next week and hope to get fortran-dev ready to merge back
to trunk.

In the mean time, I have posted a patch for the other fortran-dev
regression, PR42353.  I want to understand absolutely why it works and
then I will commit an "obvious" fix.

Cheers

Paul

On Thu, Apr 15, 2010 at 11:30 PM, janus at gcc dot gnu dot org
<gcc-bugzilla@gcc.gnu.org> wrote:
>
>
> ------- Comment #1 from janus at gcc dot gnu dot org  2010-04-15 21:30 -------
> Here is a reduced test case, which ICEs with the same backtrace:
>
>
> module m_string
>
>  type t_string
>    character, dimension(:), allocatable :: string
>  contains
>    procedure :: char => string_to_char
>  end type t_string
>
> contains
>
>  function string_to_char (s) result(res)
>    class(t_string), intent(in) :: s
>    character(len=size(s%string)) :: res
>  end function string_to_char
>
> end module m_string
>
>
> --
>
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43227
>
> ------- You are receiving this mail because: -------
> You are on the CC list for the bug, or are watching someone who is.
>



Comment 3 janus 2010-04-18 11:09:34 UTC
It turns out this problem is not specific to the OOP stuff on fortran-dev, but instead is due to an underlying problem with PROCEDURE statements (which affects procedure pointers as well as PPCs), demonstrated by this test case:


module m_string

  procedure(string_to_char) :: char1			! segfault

!   procedure(string_to_char),pointer :: char2		! segfault

!   type t_string
!     procedure(string_to_char),pointer,nopass :: char3	! segfault
!   end type t_string

contains

  function string_to_char (s) result(res)
    character, dimension(:), intent(in) :: s
    character(len=size(s)) :: res
  end function string_to_char

end module m_string


All of the three forms of the PROCEDURE statement shown above trigger the same ICE (which is also the same ICE as in comment #0 and #1, due to fortran-dev's usage of PPCs in the implementation of polymorphic TBPs).

The above test case segfaults with 4.3, works with 4.4, and then fails again with 4.5, 4.6 and fortran-dev. Therefore this PR is rather a 4.5 regression than a fortran-dev regressions.
Comment 4 Dominique d'Humieres 2010-04-18 11:48:53 UTC
Marked as a 4.5/4.6 regression.
Comment 5 Dominique d'Humieres 2010-04-18 16:18:56 UTC
What about pr42274? Is it a duplicate or not?
Comment 6 janus 2010-04-18 16:42:20 UTC
(In reply to comment #5)
> What about pr42274? Is it a duplicate or not?

I don't think so.
Comment 7 Paul Thomas 2010-04-18 17:33:54 UTC
Created attachment 20410 [details]
Fix for the problem

This needs to be regtested but I believe it to be bombproof.

However, I should attempt to find out why the resolution is not being done else where.

Paul
Comment 8 Paul Thomas 2010-04-18 18:30:25 UTC
(In reply to comment #6)
> (In reply to comment #5)
> > What about pr42274? Is it a duplicate or not?
> 
> I don't think so.
> 

My patch fixes pr42274 comment #9 but not the main part of it.  Janus is quite right that the bugs are different.

The patch regtests OK, as expected.  I will do some investigating as to the right place to do the resolution.  module.c does not look right :-)


Cheers

Paul
Cheers

Paul
Comment 9 Paul Thomas 2010-04-19 12:12:54 UTC
I decided to take a look at this during lunchtime today.  The source that I had to hand is the 20091203 4.5.0 snapshot.  To my astonishment, this does not show the problem.  I have had a quick look at the intervening gcc-cvs postings but cannot identify the source of the regression yet.  Janus's patch of 20091211 is NOT the cause.

Paul  
Comment 10 Dominique d'Humieres 2010-04-19 12:33:34 UTC
> I decided to take a look at this during lunchtime today.  The source that I had
> to hand is the 20091203 4.5.0 snapshot.  To my astonishment, this does not show
> the problem.  I have had a quick look at the intervening gcc-cvs postings but
> cannot identify the source of the regression yet.  Janus's patch of 20091211 is
> NOT the cause.

AFAICR the problem is specific to the fortran-dev branch. From my logs and my habits, I suspect that it was introduced between revisions 156573 (Feb  7 2010) and 157148 (probably at or after r157133, i.e. on or after Mon Mar  1 09:23:35 2010).
Comment 11 janus 2010-04-19 12:51:58 UTC
(In reply to comment #10)
> AFAICR the problem is specific to the fortran-dev branch.

No, this is definitely not the case! Only the failure of comment #0 is specific to the branch. However, this failure is caused by an underlying problem with procedure pointers, which is also present in the 4.5 release (see comment #3).

When searching for the origin of the regression, one should use the test case in comment #3 and look at the 4.5 trunk.
Comment 12 Dominique d'Humieres 2010-04-19 13:06:51 UTC
> When searching for the origin of the regression, one should use the test case
> in comment #3 and look at the 4.5 trunk.

I keep forgetting this test!-(on i686-apple-darwin9, it compiles at revision 147438, 20090512, and fails at revision 150825, 20090817).
Comment 13 janus 2010-04-19 13:21:47 UTC
> I keep forgetting this test!-(on i686-apple-darwin9, it compiles at revision
> 147438, 20090512, and fails at revision 150825, 20090817).

That's a start. I can see two (hypothetical) candidates in this range:

 * r150725
 * r150823

Will try to find out if one of these is the culprit.
Comment 14 janus 2010-04-19 13:46:47 UTC
(In reply to comment #13)
> > I keep forgetting this test!-(on i686-apple-darwin9, it compiles at revision
> > 147438, 20090512, and fails at revision 150825, 20090817).
> 
> That's a start. I can see two (hypothetical) candidates in this range:
> 
>  * r150725
>  * r150823

I just checked r150724, which also fails. This means that both my guesses were wrong. But at least it bring us down to the range 147438:150724 (which is still three months of development).
Comment 15 Dominique d'Humieres 2010-04-19 13:54:58 UTC
> I just checked r150724, which also fails. This means that both my guesses were
> wrong. But at least it bring us down to the range 147438:150724 (which is still
> three months of development).

I don't have access to IRC from my office desk. If you have access to it, you may ping Tobias and Jerry to ask them to look to their archives for something in between.
Comment 16 Tobias Burnus 2010-04-19 15:13:37 UTC
Works: 2009-07-24-r150035
Fails: 2009-07-29-r150196

(Both trees were _not_ clean, but the first has the same patches as the second one, plus one more - thus, it is rather likely that the regression range is still correct.)


I think the culprit is:

Date: Sat Jul 25 11:56:35 2009
New Revision: 150078
URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=150078

2009-07-25  Janus Weil  <janus@gcc.gnu.org>

        PR fortran/39630
        * decl.c (match_ppc_decl): Implement the PASS attribute for procedure
        pointer components.
[...]
        * module.c (MOD_VERSION): Bump module version.
        (binding_ppc): New string constants.
        (mio_component): Only use formal args if component is a procedure
        pointer and add 'tb' member.
        (mio_typebound_proc): Include pass_arg and take care of procedure
        pointer components.
[...]
Comment 17 janus 2010-04-19 18:47:36 UTC
(In reply to comment #16)
> I think the culprit is:
> 
> Date: Sat Jul 25 11:56:35 2009
> New Revision: 150078
> URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=150078

Close, but not quite :)

It's actually r150047, as I just found out. However, this revision only introduces the first ICE in the test case:

module m_string

  procedure(string_to_char) :: char1                    ! ICE #1

!   procedure(string_to_char),pointer :: char2          ! ICE #2

!   type t_string
!     procedure(string_to_char),pointer,nopass :: char3 ! ICE #3
!   end type t_string

contains

  function string_to_char (s) result(res)
    character, dimension(:), intent(in) :: s
    character(len=size(s)) :: res
  end function string_to_char

end module m_string


The second one is already there at r150046. For this I found a window of 147438:148816 up to now. Will try to find out more.


The third ICE is not present at 150047, but is apparently masked by another error:

    character(len=size(s)) :: res
                  1
Error: Character length of component 'char3' needs to be a constant specification expression at (1)
Comment 18 Paul Thomas 2010-04-19 18:48:41 UTC
(In reply to comment #16)
I sort of doubt it.  The problem arises because mio_symbol crashes in writing the character length of the procedure symbol:

Breakpoint 1, mio_symbol (sym=0x9d02370)
    at ../../fortran-dev/gcc/fortran/module.c:3560
3560      mio_typespec (&sym->ts);
(gdb) print sym->name
$1 = 0xb7c8c9f0 "char1"
(gdb) print sym->ts.u.cl
$2 = (gfc_charlen *) 0x9d04400
(gdb) print *sym->ts.u.cl
$3 = {length = 0x9d04420, next = 0x0, length_from_typespec = 0 '\0', 
  backend_decl = 0x0, passed_length = 0x0, resolved = 0}
(gdb) print *sym->ts.interface->ts.u.cl
$4 = {length = 0x9d03000, next = 0x9cb6be8, length_from_typespec = 0 '\0', 
  backend_decl = 0x0, passed_length = 0x0, resolved = 1}
(gdb) 

Note that the interface character length has been resolved, whereas the procedure character length has not.  This is why my patch of #7 works.  I believe that the problem must lie in resolve.c.  For some reason, the symbol's own character length expression is not being resolved.

Paul
Comment 19 Dominique d'Humieres 2010-04-19 20:13:30 UTC
Note that the patch in comment #7 fixes the test in comment #3 when the 'type t_string' block is uncommented. But there is still a "Segmentation fault" when the line

!   procedure(string_to_char),pointer :: char2          ! segfault

is uncommented.
Comment 20 Paul Thomas 2010-04-19 21:16:23 UTC
Created attachment 20429 [details]
A provisional fix for the PR

This needs cleaning up and FAILUREs of the gfc_resolve_expr's need dealing with.

Once this is done and a testcase fabricated, I will submit it - tomorrow morning, I guess.

BTW It bootstraps and regtests on trunk.

Paul
Comment 21 janus 2010-04-19 21:34:02 UTC
(In reply to comment #20)
> Created an attachment (id=20429) [edit]
> A provisional fix for the PR


Yes, the following parts are approved (they're exactly what I had in mind):

@@ -10292,6 +10298,8 @@
 		{
 		  c->ts.u.cl = gfc_new_charlen (sym->ns, ifc->ts.u.cl);
 		  gfc_expr_replace_comp (c->ts.u.cl->length, c);
+		  if (c->ts.u.cl->length && !c->ts.u.cl->resolved)
+		    gfc_resolve_expr (c->ts.u.cl->length);
 		}
 	    }
 	  else if (c->ts.interface->name[0] != '\0' && !sym->attr.vtype)
@@ -10805,6 +10813,8 @@
 	    {
 	      sym->ts.u.cl = gfc_new_charlen (sym->ns, ifc->ts.u.cl);
 	      gfc_expr_replace_symbols (sym->ts.u.cl->length, sym);
+	      if (sym->ts.u.cl->length && !sym->ts.u.cl->resolved)
+		gfc_resolve_expr (sym->ts.u.cl->length);
 	    }
 	}
       else if (sym->ts.interface->name[0] != '\0')


Could you explain what the other stuff is needed for? I currently fail to see that.
Comment 22 Paul Thomas 2010-04-20 05:00:33 UTC
(In reply to comment #21)

> 
> Could you explain what the other stuff is needed for? I currently fail to see
> that.
> 

Ignore the first bit in resolve.c,

The change to trans-decl.c fixes the second segfault.  The procedure pointers do not need a character length to do their job.  So rather than making a decl for it, we just charge through.  It needs a gcc_assert to make sure that we don't let everything through.

Watch this space!

Paul
Comment 23 Paul Thomas 2010-04-20 06:19:32 UTC
Created attachment 20433 [details]
fix for this PR and PR43266

The attached is what I intend to submit tonight, unless somebody approves it in the mean time.  Obviously, the patch needs ChangeLogs.

Also included is the fix for PR43266, which was first posted on March 27 and is very 'obvious'.

Bootstrapped and regtested on FC9/x86_64 and RHEL5.4/i686

OK?
Comment 24 Dominique d'Humieres 2010-04-20 09:18:31 UTC
The patch in comment #23 works fine on my tests. Thanks for it.

> Also included is the fix for PR43266, which was first posted on March 27 and is
> very 'obvious'.

Note for the record that it gives an additional error for PR43266 instead of the ICE:

pr43266.f90:37.25:

   CALL obj%middle%proc_b
                         1
Error: 'proc_b' at (1) should be a SUBROUTINE
Comment 25 paul.richard.thomas@gmail.com 2010-04-20 09:31:37 UTC
Subject: Re:  [4.5/4.6 Regression] ICE: segmentation fault 
	in mio_expr

Dominiq,
>
> Note for the record that it gives an additional error for PR43266 instead of
> the ICE:
>
> pr43266.f90:37.25:
>
>   CALL obj%middle%proc_b
>                         1
> Error: 'proc_b' at (1) should be a SUBROUTINE


Yes, indeed.  This appears in the testcase and results from the module
not being written.

Paul
Comment 26 Paul Thomas 2010-04-20 19:07:48 UTC
Subject: Bug 43227

Author: pault
Date: Tue Apr 20 19:07:14 2010
New Revision: 158570

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=158570
Log:
2010-04-20  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/43227
	* resolve.c (resolve_fl_derived): If a component character
	length has not been resolved, do so now.
	(resolve_symbol): The same as above for a symbol character
	length.
	* trans-decl.c (gfc_create_module_variable): A 'length' decl is
	not needed for a character valued, procedure pointer.

	PR fortran/43266
	* resolve.c (ensure_not_abstract_walker): If 'overriding' is
	not found, return FAILURE rather than ICEing.

2010-04-20  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/43227
	* gfortran.dg/proc_decl_23.f90: New test.

	PR fortran/43266
	* gfortran.dg/abstract_type_6.f03: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/abstract_type_6.f03
    trunk/gcc/testsuite/gfortran.dg/proc_decl_23.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/testsuite/ChangeLog

Comment 27 Paul Thomas 2010-04-21 04:27:23 UTC
Fixed on trunk - will do 4.5 next week.

Paul
Comment 28 Paul Thomas 2010-04-24 12:29:49 UTC
Subject: Bug 43227

Author: pault
Date: Sat Apr 24 12:29:23 2010
New Revision: 158687

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=158687
Log:
2010-04-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/43227
	* resolve.c (resolve_fl_derived): If a component character
	length has not been resolved, do so now.
	(resolve_symbol): The same as above for a symbol character
	length.
	* trans-decl.c (gfc_create_module_variable): A 'length' decl is
	not needed for a character valued, procedure pointer.

	PR fortran/43266
	* resolve.c (ensure_not_abstract_walker): If 'overriding' is
	not found, return FAILURE rather than ICEing.

2010-04-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/43227
	* gfortran.dg/proc_decl_23.f90: New test.

	PR fortran/43266
	* gfortran.dg/abstract_type_6.f03: New test.

Added:
    branches/gcc-4_5-branch/gcc/testsuite/gfortran.dg/abstract_type_6.f03
    branches/gcc-4_5-branch/gcc/testsuite/gfortran.dg/proc_decl_23.f90
Modified:
    branches/gcc-4_5-branch/gcc/fortran/ChangeLog
    branches/gcc-4_5-branch/gcc/fortran/resolve.c
    branches/gcc-4_5-branch/gcc/fortran/trans-decl.c
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog

Comment 29 Paul Thomas 2010-04-24 12:30:58 UTC
Fixed on trunk and 4.5.

Thanks, as ever, Dominique!

Paul