https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81986
kargl at gcc dot gnu.org changed:
What|Removed |Added
CC||dodji at gcc dot gnu.org,
||dvyukov at gcc dot gnu.org,
||jakub at gcc dot gnu.org,
||kcc at gcc dot gnu.org,
||marxin at gcc dot gnu.org
Component|libfortran |sanitizer
--- Comment #1 from kargl at gcc dot gnu.org ---
(In reply to Vittorio Zecca from comment #0)
> ! from test case pr66311.f90
> ! must be compiled and run
> ! libgfortran/runtime/string.c:199:11: runtime error: negation of
> 0x8000 cannot be represented in type '__int128';
> cast to an unsigned type to negate this value to itself
> character(len=100) :: buffer
> write(buffer,*) -huge(0_16)-1
> end
Doesn't look like a gfortran problem other than gfortran uses GCC's
__int128 type and its middle/backend machinery. If you compile
your code with -fdump-tree-original, you get in a.f90.003t.original
{
static integer(kind=16) C.3427 = -0x8000;
_gfortran_transfer_integer_write (_parm.0, , 16);
}
Changing your code to
character(len=100) :: buffer
write(buffer,*) -huge(0_4)-1
print '(A,Z8)', trim(buffer)// ' 0x', -huge(0_4)-1
end
where I added the print statement gives
troutmask:sgk[264] gfortran6 -static -o z -fdump-tree-original a.f90 && ./z
-2147483648 0x8000
and a.f90.003t.original contains
{
static integer(kind=4) C.3427 = -2147483648;
_gfortran_transfer_integer_write (_parm.0, , 4);
}
Note the difference between using a decimal representation for the
constant and the hexidecimal representation in the *.original file.
But, a more interesting result occurs for
int
main(void)
{
__int128 i,j;
i = ((__int128)1) << 127;
j = (-((__int128)1)) << 127;
return 0;
}
% /usr/local/bin/gcc6 -fdump-tree-original -c a.c
%/ cat a.c.003t.original
;; Function main (null)
;; enabled by -tree-original
{
__int128 i;
__int128 j;
__int128 i;
__int128 j;
i = -0x8000;
j = -0x8000;
}
return 0;
Why is this interesting? Well, consider the simpler case
int
main(void)
{
int i,j;
i = ((int)1) << 31;
j = -(((int)1) << 31);
return 0;
}
/usr/local/bin/gcc6 -fdump-tree-original -c a.c
a.c: In function 'main':
a.c:9:8: warning: integer overflow in expression [-Woverflow]
j = -(((int)1)<<31);
^
%cat a.c.003t.original
;; Function main (null)
;; enabled by -tree-original
{
int i;
int j;
int i;
int j;
i = -2147483648;
j = -2147483648(OVF);
return 0;
}
Note, both the warning that GCC issues and the (OVF) annotation.
So, in summary, not a gfortran. Someone needs to teach the sanitizers
about GCC's __int128 or someone needs to fix the handling of __int128
to mirror the behavior observed for a plain old int.