http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59604

--- Comment #5 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
On Fri, Dec 27, 2013 at 07:53:00PM +0000, tkoenig at gcc dot gnu.org wrote:
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59604
> 
> Thomas Koenig <tkoenig at gcc dot gnu.org> changed:
> 
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>              Blocks|                            |58003
> 
> --- Comment #4 from Thomas Koenig <tkoenig at gcc dot gnu.org> ---
> (In reply to kargl from comment #2)
> > (In reply to Thomas Koenig from comment #1)
> > > TRANSFER gets this right.
> > 
> > It is unclear what you mean here.
> 
> What I mean is that
> 
> program test
>   if (transfer(z'FFFFFFFF',1) /= -1) call abort
> end program test
> 
> does not call abort.

I suspect that the above is not portable as transfer() simply copies
bits.  z'FFFFFFF' is an integer(8) (or integer(16)) entity.  Transfer()
is copying 32-bits from that entity.  It is clear from the 
-fdump-tree-original that middle-end is "converting" the resulting
32-bit thing into -1.  So, you're relying on twos-complement wrap
around semantics.

> Also setting this as blocking 58003, because an obvious
> fix to that bug would replace an ICE with a wrong-code
> bug for some corner cases (not preferable :-)

This isn't blocking 58003 as the code in 59604 is invalid.  As gfortran
provides popcnt() as an intrinsics procedure, it follows that popcnt()
should follow the Fortran standard (see below quote).  Now, if you want
to chase a real bug in gfortran, try this little program

program test
   integer(8) :: i = 4294967295_8
   integer(8) :: j = z'FFFFFFFF'
   !
   ! The following two lines should call abort, but don't!  In addition,
   ! these lines do not require -fno-range-check to compile, so gfortran
   ! violates the quote from the F95 standard (p.228) below.
   !
   if (int(i) /= -1) call abort
   if (int(j) /= -1) call abort
   !
   ! On a 2-complement system, the next statement is optimized away.
   ! I haven't decided yet, whether transfer() violates the standard
   ! because it only copies bits and the 32-bits copied from the boz
   ! fit into an integer(4).
   !
   if (transfer(z'FFFFFFFF',1) /= -1) call abort
   !
   ! Both of these require -fno-range-check to compile, and they violate
   !
   !    A program is prohibited from invoking an intrinsic procedure
   !    under circumstances where a value to be returned in a subroutine
   !    argument or function result is outside the range of values
   !    representable by objects of the specified type and type parameters.
   !
   ! 4294967295_8 is well outside of the range [-huge()-1:huge()] of a
   ! twos-complement 32-bit integer(4)
   !
   if (int(z'FFFFFFFF') /= -1) call abort
   if (int(4294967295_8) /= -1) call abort
end program test

Reply via email to