This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug fortran/77941] ICE in expand_expr_addr_expr_1, at expr.c:7805


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77941

--- Comment #8 from Janne Blomqvist <jb at gcc dot gnu.org> ---
(In reply to Steve Kargl from comment #7)
> On Thu, Mar 22, 2018 at 07:53:14AM +0000, jb at gcc dot gnu.org wrote:
> >
> > It works on x86_64-pc-linux-gnu (including running it), but the ICE remains on
> > i686-pc-linux-gnu.
> > 
> 
> Janne, thanks for checking.  2_8**32+1 is 4GB+1byte of memory.
> Without PAE, i686 is limited to less than 4GB once an OS grabs a
> small portion of wired memory.  Do we care if an ICE occurs?
> I suppose one could always check that a length type parameter
> less than some max integer based on 32-bit vs 64-bit system, 
> but that would pessimize all uses of strings as this would 
> need to be a runtime check.

If one looks at the -fdump-tree-original dumps, for both i686 and x86-64 the
function f() looks Ok. However, the program p differs significantly. For x86-64
the working program p is:


p ()
{
  static void f (character(kind=1)[1:] &, integer(kind=8), integer(kind=8));

  {
    struct __st_parameter_dt dt_parm.0;

    dt_parm.0.common.filename = &"z.f90"[1]{lb: 1 sz: 1};
    dt_parm.0.common.line = 2;
    dt_parm.0.common.flags = 128;
    dt_parm.0.common.unit = 6;
    _gfortran_st_write (&dt_parm.0);
    {
      character(kind=1)[1:4294967297] * pstr.1;
      void * restrict D.3781;

      D.3781 = (void * restrict) __builtin_malloc (4294967297);
      pstr.1 = (character(kind=1)[1:4294967297] *) D.3781;
      f (pstr.1, 4294967297, 4294967297);
      _gfortran_transfer_character_write (&dt_parm.0, pstr.1, 4294967297);
      __builtin_free ((void *) pstr.1);
    }
    _gfortran_st_write_done (&dt_parm.0);
  }
}


whereas for i686 we have:


p ()
{
  static void f (character(kind=1)[1:] &, integer(kind=4), integer(kind=8));

  {
    struct __st_parameter_dt dt_parm.0;

    dt_parm.0.common.filename = &"z.f90"[1]{lb: 1 sz: 1};
    dt_parm.0.common.line = 2;
    dt_parm.0.common.flags = 128;
    dt_parm.0.common.unit = 6;
    _gfortran_st_write (&dt_parm.0);
    {
      character(kind=1) str.1[1];

      f ((character(kind=1)[1:1] *) &str.1, 1(OVF), 4294967297);
      _gfortran_transfer_character_write (&dt_parm.0, (character(kind=1)[1:1]
*) &str.1, 1(OVF));
    }
    _gfortran_st_write_done (&dt_parm.0);
  }
}


So evidently for i686 the frontend realizes that the size of the result array
overflows and then skips malloc()'ing space for it. So I guess in some way it
should be possible for the frontend to detect the overflow and abort before we
get the ICE.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]