GCC screws up pointer->ulong conversion on 32 bit systems

Iain Buclaw ibuclaw at ubuntu.com
Sat Nov 9 09:01:43 PST 2013


On 9 November 2013 12:19, Johannes Pfau <nospam at example.com> wrote:

> ----------------------------------------------
> #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);
>
>
That code does seem to contradict what the comment is saying.  I'll raise
it in #gcc and send a patch  (unless you want to do it).


-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/d.gnu/attachments/20131109/349c03a8/attachment.html>


More information about the D.gnu mailing list