GCC screws up pointer->ulong conversion on 32 bit systems
Johannes Pfau
nospam at example.com
Sat Nov 9 04:19:19 PST 2013
----------------------------------------------
#include <stdio.h>
#include <stdint.h>
void test(void* p)
{
uint64_t pl = (uint64_t)p;
uint64_t p2 = (uint64_t)(int)p;
int tmp = (int)p;
uint64_t p3 = (uint64_t)tmp;
printf("%llx %llx %llx\n", pl, p2, p3);
}
void main()
{
void* p = (void*)0xFFEECCAA;
test(p);
}
-----------------------------------------------
Output is:
ffffffffffeeccaa ffffffffffeeccaa ffffffffffeeccaa
Expected:
ffeeccaa ffffffffffeeccaa ffffffffffeeccaa
Unfortunately this affects us as well (the bug is in
convert_to_integer). What do you think, is this a valid GCC bug which
should be filed?
I verified the C testcase on ARM and x86. I don't have a x86 gdc right
now, could you test whether the D testcase
http://dpaste.dzfl.pl/abb9a6971
also fails on x86?
The fix is simple:
in gcc/convert.c(convert_to_integer):
/* Convert to an unsigned integer of the correct width first, and
from there widen/truncate to the required type. Some targets support
the coexistence of multiple valid pointer sizes, so fetch the one we
need from the type. */
expr = fold_build1 (CONVERT_EXPR,
lang_hooks.types.type_for_size
(TYPE_PRECISION (intype), 0),
expr);
should be
/* Convert to an unsigned integer of the correct width first, and
from there widen/truncate to the required type. Some targets support
the coexistence of multiple valid pointer sizes, so fetch the one we
need from the type. */
expr = fold_build1 (CONVERT_EXPR,
lang_hooks.types.type_for_size
(TYPE_PRECISION (intype), 1),
expr);
More information about the D.gnu
mailing list