[Bug fortran/77941] ICE in expand_expr_addr_expr_1, at expr.c:7805
sgk at troutmask dot apl.washington.edu
gcc-bugzilla@gcc.gnu.org
Thu Mar 22 17:30:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77941
--- Comment #10 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
On Thu, Mar 22, 2018 at 02:27:25PM +0000, jb at gcc dot gnu.org wrote:
> 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:
>
Dumps compressed down to needed lines.
x86_64
> static void f (character(kind=1)[1:] &, integer(kind=8), integer(kind=8));
>
> character(kind=1)[1:4294967297] * pstr.1;
> void * restrict D.3781;
>
> D.3781 = (void * restrict) __builtin_malloc (4294967297);
i686
> static void f (character(kind=1)[1:] &, integer(kind=4), integer(kind=8));
>
> 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));
The dumps are a little misleading in that f(n) is inlined.
Here, the middle/backend can see n = 2_8**32+1, so it can
generate the OVF.
If f(n) is in a file by itself the dump looks much different.
(where I've wrapped long lines and this is on x86_64 and
comments in-lined.).
f (character(kind=1)[1:..__result] & __result, integer(kind=8)
.__result, integer(kind=8) n)
{
integer(kind=8) ..__result;
bitsizetype D.3766;
sizetype D.3767;
..__result = MAX_EXPR <n, 0>;
So, gfortran (or middle/backend) protect against a negative
number on i686 .__result is int32. The above MAXEXPR may cause
2-complement wrap around. What I want to avoid is
if (n >= intmax_t)
{
runtime error here.
}
for all routines that take a string.
D.3766 = (bitsizetype)(sizetype)NON_LVALUE_EXPR<..__result> * 8;
D.3767 = (sizetype) NON_LVALUE_EXPR <..__result>;
{
integer(kind=8) D.3764;
integer(kind=8) D.3765;
D.3764 = ..__result;
D.3765 = NON_LVALUE_EXPR <D.3764> + -1;
if (D.3764 > 0)
{
if (NON_LVALUE_EXPR <D.3764> > 1)
{
__builtin_memmove ((void *) __result,
(void *) &"a"[1]{lb: 1 sz: 1}, 1);
__builtin_memset ((void *) __result + 1, 32,i
(unsigned long) D.3765);
}
else
{
__builtin_memmove ((void *) __result,
(void *) &"a"[1]{lb: 1 sz: 1},
(unsigned long) NON_LVALUE_EXPR <D.3764>);
}
}
}
}
More information about the Gcc-bugs
mailing list