Bug 41869 - ICE segfault when reading module file
ICE segfault when reading module file
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.5.0
: P3 normal
: ---
Assigned To: Paul Thomas
: ice-on-valid-code
Depends on:
Blocks: 32834
  Show dependency treegraph
 
Reported: 2009-10-29 15:16 UTC by Tobias Burnus
Modified: 2010-02-16 10:53 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-02-15 11:57:25


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2009-10-29 15:16:33 UTC
The following program ICEs with
  test.f90:25:0: internal compiler error: Segmentation fault

The problem is related to PUBIC vs. PRIVATE visibility. It is no regression as 4.1.2, 4.2.1, 4.3.3, 4.4.1 and 4.5 crash. The program compiles with NAG f95 and g95.

Valgrind shows:
==31812== Invalid read of size 8
==31812==    at 0x4F4B80: mio_pointer_ref (module.c:2233)
==31812==    by 0x6D05D0F: ???
==31812==    by 0x4F6698: mio_symbol_ref (module.c:2494)
==31812==    by 0x4F7137: mio_expr (module.c:3029)

gdb shows:
Program received signal SIGSEGV, Segmentation fault.
mio_pointer_ref (gp=0x28) at /home/tob/projects/gcc-trunk-checkout/gcc/fortran/module.c:2233
2233          p = get_pointer (*((char **) gp));
(gdb) bt
#0  mio_pointer_ref (gp=0x28) at /home/tob/projects/gcc-trunk-checkout/gcc/fortran/module.c:2233
#1  0x00000000004f6699 in mio_symbol_ref (symp=<value optimized out>) at /home/tob/projects/gcc-trunk-checkout/gcc/fortran/module.c:2494
#2  0x00000000004f7138 in mio_expr (ep=0x13a96c0) at /home/tob/projects/gcc-trunk-checkout/gcc/fortran/module.c:3029
#3  0x00000000004f7a7a in mio_array_spec (asp=<value optimized out>) at /home/tob/projects/gcc-trunk-checkout/gcc/fortran/module.c:2134
#4  0x00000000004f7d07 in mio_symbol (sym=0x13a7930) at /home/tob/projects/gcc-trunk-checkout/gcc/fortran/module.c:3540
#5  0x00000000004f81d0 in write_symbol (n=40, sym=0x13a7930) at /home/tob/projects/gcc-trunk-checkout/gcc/fortran/module.c:4725
#6  0x00000000004f8360 in write_symbol0 (st=<value optimized out>) at /home/tob/projects/gcc-trunk-checkout/gcc/fortran/module.c:4765



module fox_m_fsys_array_str
contains
  pure function str_vs(vs) result(s)
    character, dimension(:), intent(in) :: vs
    character(len=size(vs)) :: s
    s = transfer(vs, s)
  end function str_vs
  pure function vs_str(s) result(vs)
    character(len=*), intent(in) :: s
    character, dimension(len(s)) :: vs
    vs = transfer(s, vs)
  end function vs_str
end module fox_m_fsys_array_str
module fox_m_fsys_format
  private
  interface str
    module procedure  str_logical_array
  end interface str
  interface len
    module procedure str_logical_array_len
  end interface
  public :: str
contains
  pure function str_logical_array_len(la) result(n)
    logical, dimension(:), intent(in)   :: la
  end function str_logical_array_len
  pure function str_logical_array(la) result(s)
    logical, dimension(:), intent(in)   :: la
    character(len=len(la)) :: s
  end function str_logical_array
  pure function checkFmt(fmt) result(good)
    character(len=*), intent(in) :: fmt
    logical :: good
    good = len(fmt) > 0
  end function checkFmt
end module fox_m_fsys_format
module m_dom_dom
  use fox_m_fsys_array_str, only: str_vs, vs_str
end module m_dom_dom
module FoX_dom
  use fox_m_fsys_format
  use m_dom_dom
end module FoX_dom
Comment 1 Daniel Franke 2009-12-06 15:18:49 UTC
Slightly reduced testcase:

module fox_m_fsys_array_str
contains
  pure function str_vs(vs) result(s)
    character, dimension(:), intent(in) :: vs
    character(len=size(vs)) :: s
  end function str_vs
  pure function vs_str(s) result(vs)
    character(len=*), intent(in) :: s
    character, dimension(len(s)) :: vs
  end function vs_str
end module fox_m_fsys_array_str
module fox_m_fsys_format
  private
  interface str
    module procedure  str_logical_array
  end interface str
  interface len
    module procedure str_logical_array_len
  end interface
  public :: str
contains
  pure integer function str_logical_array_len(la)
    logical, dimension(:), intent(in)   :: la
  end function str_logical_array_len
  pure function str_logical_array(la) result(s)
    logical, dimension(:), intent(in)   :: la
    character(len=len(la)) :: s
  end function str_logical_array
  pure logical function checkFmt(fmt)
    character(len=*), intent(in) :: fmt
    checkFmt = len(fmt) > 0
  end function checkFmt
end module fox_m_fsys_format
module FoX_dom
  use fox_m_fsys_format
  use fox_m_fsys_array_str
end module FoX_dom
Comment 2 Tobias Burnus 2010-02-03 20:40:46 UTC
Paul, maybe you have an idea how to solve this best.

One has two modules, (1) one defines "vs_str" and the other (2) defines
  interface
    module procedure len
  end interface
  PRIVATE :: len
  (and a public interface which uses "len")

Now in a third (3) module, one loads first module (2) and then module (1); when writing the .mod for (3) one writes the following symbol of module (1):

  pure function vs_str(s) result(vs)
    character(len=*), intent(in) :: s
    character, dimension(len(s)) :: vs

Now when writing the expression for the upper bound of "vs" (viz. "len(s)"), one has  e->expr_type == EXPR_FUNCTION but e->symtree == NULL, which crashes.

Note: mio_expr calls fix_mio_expr(), which tries to fix it for the intrinsic "len", but
  e->symtree = gfc_find_symtree (gfc_current_ns->sym_root, fname);
returns NULL.

On solution I see is to create a new symtree and add it in fix_mio_expr via gfc_get_intrinsic_sub_symbol, but somehow I think "len" should not have disappeared at the first place.

The crash happens in mio_symtree_ref which simply checks whether the symbol needs to be written or whether it has been written already. For an intrinsic fucntion, it does not matter and could thus be skipped (not checked!). For output, mio_expr then simply writes "0" (for intrinsic function) and "len" (for the function name) - albeit with accessing the e->symtree. Thus, one could also modify "EXPR_FUNCTION:" of mio_expr to for e->symtree == NULL and (iomode == IO_OUTPUT) but that means some code replication.
Comment 3 paul.richard.thomas@gmail.com 2010-02-04 05:33:32 UTC
Subject: Re:  ICE segfault when reading module file

Tobias,

I'll give it some thought at lunchtime.

Cheers

Paul

On Wed, Feb 3, 2010 at 9:40 PM, burnus at gcc dot gnu dot org
<gcc-bugzilla@gcc.gnu.org> wrote:
>
>
> ------- Comment #2 from burnus at gcc dot gnu dot org  2010-02-03 20:40 -------
> Paul, maybe you have an idea how to solve this best.
>
> One has two modules, (1) one defines "vs_str" and the other (2) defines
>  interface
>    module procedure len
>  end interface
>  PRIVATE :: len
>  (and a public interface which uses "len")
>
> Now in a third (3) module, one loads first module (2) and then module (1); when
> writing the .mod for (3) one writes the following symbol of module (1):
>
>  pure function vs_str(s) result(vs)
>    character(len=*), intent(in) :: s
>    character, dimension(len(s)) :: vs
>
> Now when writing the expression for the upper bound of "vs" (viz. "len(s)"),
> one has  e->expr_type == EXPR_FUNCTION but e->symtree == NULL, which crashes.
>
> Note: mio_expr calls fix_mio_expr(), which tries to fix it for the intrinsic
> "len", but
>  e->symtree = gfc_find_symtree (gfc_current_ns->sym_root, fname);
> returns NULL.
>
> On solution I see is to create a new symtree and add it in fix_mio_expr via
> gfc_get_intrinsic_sub_symbol, but somehow I think "len" should not have
> disappeared at the first place.
>
> The crash happens in mio_symtree_ref which simply checks whether the symbol
> needs to be written or whether it has been written already. For an intrinsic
> fucntion, it does not matter and could thus be skipped (not checked!). For
> output, mio_expr then simply writes "0" (for intrinsic function) and "len" (for
> the function name) - albeit with accessing the e->symtree. Thus, one could also
> modify "EXPR_FUNCTION:" of mio_expr to for e->symtree == NULL and (iomode ==
> IO_OUTPUT) but that means some code replication.
>
>
> --
>
> burnus at gcc dot gnu dot org changed:
>
>           What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                 CC|                            |pault at gcc dot gnu dot org
>
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41869
>
> ------- You are receiving this mail because: -------
> You are on the CC list for the bug, or are watching someone who is.
>



Comment 4 Paul Thomas 2010-02-05 16:28:11 UTC
(In reply to comment #3)
> Subject: Re:  ICE segfault when reading module file
> 
> Tobias,
> 
> I'll give it some thought at lunchtime.

I did give it some thought but got interrupted in writing my reply.

As long as the LEN intrinsic is referenced in an public procedure in module fox_m_fsys_format, the problem goes away and gfortran behaves correctly.  I'll take a look at your suggested fixes.

Paul
Comment 5 Paul Thomas 2010-02-08 18:19:10 UTC
Please excuse the lack of a diff - I was using a snap shot to work on this PR.  This fixes the problem but I do not know if it regtests; however, I believe it to be good.  If somebody wants to take it to completion, please be my guest.  Otherwise, I'll do the job at the weekend.

Paul

static void
fix_mio_expr (gfc_expr *e)
{
  gfc_symtree *ns_st = NULL;
  gfc_symbol *sym;
  const char *fname;

  if (iomode != IO_OUTPUT)
    return;

  if (e->symtree)
    {
      /* If this is a symtree for a symbol that came from a contained module
	 namespace, it has a unique name and we should look in the current
	 namespace to see if the required, non-contained symbol is available
	 yet. If so, the latter should be written.  */
      if (e->symtree->n.sym && check_unique_name (e->symtree->name))
	ns_st = gfc_find_symtree (gfc_current_ns->sym_root,
				  e->symtree->n.sym->name);

      /* On the other hand, if the existing symbol is the module name or the
	 new symbol is a dummy argument, do not do the promotion.  */
      if (ns_st && ns_st->n.sym
	  && ns_st->n.sym->attr.flavor != FL_MODULE
	  && !e->symtree->n.sym->attr.dummy)
	e->symtree = ns_st;
    }
  else if (e->expr_type == EXPR_FUNCTION && e->value.function.name)
    {
      /* In some circumstances, a function used in an initialization
	 expression, in one use associated module, can fail to be
	 coupled to its symtree when used in a specification
	 expression in another module.  */
      fname = e->value.function.esym ? e->value.function.esym->name
				     : e->value.function.isym->name;
      e->symtree = gfc_find_symtree (gfc_current_ns->sym_root, fname);

      if (e->symtree)
	return;

      /* This is probably a reference to a private procedure from another
	 module.  To prevent a segfault, make a generic with no specific
	 instances.  If this module is used, without the required
	 specific coming from somewhere, the appropriate error message
	 is issued.  */
      gfc_get_symbol (fname, gfc_current_ns, &sym);
      sym->attr.flavor = FL_PROCEDURE;
      sym->attr.generic = 1;
      e->symtree = gfc_find_symtree (gfc_current_ns->sym_root, fname);
    }
}

Comment 6 Tobias Burnus 2010-02-09 17:33:07 UTC
Subject: Bug 41869

Author: burnus
Date: Tue Feb  9 17:32:53 2010
New Revision: 156631

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

        PR fortran/41869
        * module.c (fix_mio_expr): Fix for private generic procedures.

2010-02-09  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41869
        * gfortran.dg/module_write_1.f90: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/module_write_1.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/module.c
    trunk/gcc/testsuite/ChangeLog

Comment 7 Paul Thomas 2010-02-15 11:57:25 UTC
Since Tobias and I already did the business on trunk, I suppose that one of us should take ownership of it.

Do we backport to 4.4 or just close it?  I would go for the backporting.

Paul
Comment 8 Tobias Burnus 2010-02-16 07:39:54 UTC
(In reply to comment #7)
> Do we backport to 4.4 or just close it?  I would go for the backporting.

Ditto. (Don't forget "gfc_symbol *sym;" as I did in my posted patch as I failed to split three patches correctly.)
Comment 9 paul.richard.thomas@gmail.com 2010-02-16 08:59:19 UTC
Subject: Re:  ICE segfault when reading module file

> Ditto. (Don't forget "gfc_symbol *sym;" as I did in my posted patch as I failed
> to split three patches correctly.)

***grin***

OK - Paul
Comment 10 Tobias Burnus 2010-02-16 10:51:13 UTC
Subject: Bug 41869

Author: burnus
Date: Tue Feb 16 10:50:56 2010
New Revision: 156799

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

        PR fortran/41869
        * module.c (fix_mio_expr): Fix for private generic procedures.

2010-02-16  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41869
        * gfortran.dg/module_write_1.f90: New test.


Added:
    branches/gcc-4_4-branch/gcc/testsuite/gfortran.dg/module_write_1.f90
Modified:
    branches/gcc-4_4-branch/gcc/fortran/ChangeLog
    branches/gcc-4_4-branch/gcc/fortran/module.c
    branches/gcc-4_4-branch/gcc/testsuite/ChangeLog

Comment 11 Tobias Burnus 2010-02-16 10:53:12 UTC
... and FIXED it myself.

Thanks again for the fix, Paul. (I refrain from thanking myself for reporting the bug ;-)
Comment 12 paul.richard.thomas@gmail.com 2010-02-16 11:01:18 UTC
Subject: Re:  ICE segfault when reading module file

Aahhh... thanks, I was going to attend to it myself.

Well thank you for the report :-)

Paul

On Tue, Feb 16, 2010 at 11:53 AM, burnus at gcc dot gnu dot org
<gcc-bugzilla@gcc.gnu.org> wrote:
>
>
> ------- Comment #11 from burnus at gcc dot gnu dot org  2010-02-16 10:53 -------
> ... and FIXED it myself.
>
> Thanks again for the fix, Paul. (I refrain from thanking myself for reporting
> the bug ;-)
>
>
> --
>
> burnus at gcc dot gnu dot org changed:
>
>           What    |Removed                     |Added
> ----------------------------------------------------------------------------
>             Status|ASSIGNED                    |RESOLVED
>         Resolution|                            |FIXED
>
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41869
>
> ------- You are receiving this mail because: -------
> You are on the CC list for the bug, or are watching someone who is.
> You are the assignee for the bug, or are watching the assignee.
>