When compiling this code to 64-bit.
app.d
----
import std.stdio;
void main()
{
ubyte u1 = cast(byte)-1;
byte u2 = cast(short)-1;
uint u3 = cast(int)-1;
int u4 = cast(long)-1;
writefln("%d", u1);
writefln("%d", u2);
writefln("%d", u3);
writefln("%d\n", u4);
writefln("long.sizeof: %d ulong.max: %20d", ulong.sizeof, ulong.max);
writefln("long.sizeof: %d long max: %20d", long.sizeof, long.max);
}
----
Prints this:
----
255
-1
4294967295
-1
long.sizeof: 8 ulong.max: 4294967295
long.sizeof: 8 long max: 9223372036854775807
----
"ulong.max" value is incorrect
Tested with dmd version 2.056, 2.057, 2.058, 2.059, 2.060 and 2.061
No problem when compiling to 32-bit.
Comment #1 by hsteoh — 2013-02-08T22:11:13Z
Which version of DMD/druntime/phobos produces this output? I've tried checkin out various versions of DMD and druntime and I can't seem to find a revision that exhibits this bug. I'm on x86-64 Linux.
Comment #2 by hsteoh — 2013-02-08T22:23:12Z
Hmm, this is very strange. I found that the bug only happens with the exact code posted above. I was testing a program that just printed the value of ulong.max, and it was correct. But the above code does indeed display the bug!
Then I added "pragma(msg, ulong.max)" and it displays the correct value.
Furthermore, commenting out "writefln("%d\n", u4)" causes the right value to be printed when running the program. Looks like there may be some kind of stack corruption or template crosstalk, not really directly related to the value of ulong.max.
Will investigate this odd issue more carefully...
Comment #3 by hsteoh — 2013-02-09T07:51:35Z
Seems that something is wrong with the codegen. To probe this problem, I made a slight modification to the code:
-------------
import std.stdio;
void marker() {}
void main()
{
ubyte u1 = cast(byte)-1;
byte u2 = cast(short)-1;
uint u3 = cast(int)-1;
int u4 = cast(long)-1;
writefln("%d", u1);
writefln("%d", u2);
writefln("%d", u3);
version(WithBug) writefln("%d\n", u4);
marker();
writefln("long.sizeof: %d ulong.max: %20d", ulong.sizeof, ulong.max);
writefln("long.sizeof: %d long max: %20d", long.sizeof, long.max);
}
--------------
When compiling with dmd -m64, here's the assembly:
0000000000424ce8 <_Dmain>:
424ce8: 55 push %rbp
424ce9: 48 8b ec mov %rsp,%rbp
424cec: 48 83 ec 10 sub $0x10,%rsp
424cf0: b0 ff mov $0xff,%al
424cf2: b1 ff mov $0xff,%cl
424cf4: 88 4d f8 mov %cl,-0x8(%rbp)
424cf7: ba ff ff ff ff mov $0xffffffff,%edx
424cfc: 89 55 fc mov %edx,-0x4(%rbp)
424cff: 48 8b 15 e2 5f 02 00 mov 0x25fe2(%rip),%rdx # 44ace8 <_TMP0+0x8>
424d06: 48 8b 35 d3 5f 02 00 mov 0x25fd3(%rip),%rsi # 44ace0 <_TMP0>
424d0d: 48 89 c7 mov %rax,%rdi
424d10: e8 8b 00 00 00 callq 424da0 <void std.stdio.writefln!(immutable(char)[], ubyte).writefln(immutable(char)[], ubyte)>
424d15: 48 8b 15 cc 5f 02 00 mov 0x25fcc(%rip),%rdx # 44ace8 <_TMP0+0x8>
424d1c: 48 8b 35 bd 5f 02 00 mov 0x25fbd(%rip),%rsi # 44ace0 <_TMP0>
424d23: 40 8a 7d f8 mov -0x8(%rbp),%dil
424d27: e8 28 4f 00 00 callq 429c54 <void std.stdio.writefln!(immutable(char)[], byte).writefln(immutable(char)[], byte)>
424d2c: 48 8b 15 b5 5f 02 00 mov 0x25fb5(%rip),%rdx # 44ace8 <_TMP0+0x8>
424d33: 48 8b 35 a6 5f 02 00 mov 0x25fa6(%rip),%rsi # 44ace0 <_TMP0>
424d3a: 8b 7d fc mov -0x4(%rbp),%edi
424d3d: e8 12 5a 00 00 callq 42a754 <void std.stdio.writefln!(immutable(char)[], uint).writefln(immutable(char)[], uint)>
424d42: e8 99 ff ff ff callq 424ce0 <void test.marker()>
424d47: 48 8b 0d da 5f 02 00 mov 0x25fda(%rip),%rcx # 44ad28 <_TMP1+0x8>
424d4e: 48 8b 05 cb 5f 02 00 mov 0x25fcb(%rip),%rax # 44ad20 <_TMP1>
424d55: 48 89 c2 mov %rax,%rdx
424d58: 48 be 08 00 00 00 00 movabs $0x8,%rsi
424d5f: 00 00 00
424d62: 48 bf ff ff ff ff ff movabs $0xffffffffffffffff,%rdi
424d69: ff ff ff
424d6c: e8 53 64 00 00 callq 42b1c4 <void std.stdio.writefln!(immutable(char)[], ulong, ulong).writefln(immutable(char)[], ulong, ulong)>
424d71: 48 8b 0d f0 5f 02 00 mov 0x25ff0(%rip),%rcx # 44ad68 <_TMP2+0x8>
424d78: 48 8b 05 e1 5f 02 00 mov 0x25fe1(%rip),%rax # 44ad60 <_TMP2>
424d7f: 48 89 c2 mov %rax,%rdx
424d82: 48 be 08 00 00 00 00 movabs $0x8,%rsi
424d89: 00 00 00
424d8c: 48 bf ff ff ff ff ff movabs $0x7fffffffffffffff,%rdi
424d93: ff ff 7f
424d96: e8 fd 6e 00 00 callq 42bc98 <void std.stdio.writefln!(immutable(char)[], ulong, long).writefln(immutable(char)[], ulong, long)>
424d9b: 31 c0 xor %eax,%eax
424d9d: c9 leaveq
424d9e: c3 retq
424d9f: 90 nop
When compiling with dmd -m64 -version=WithBug, here's the assembly:
0000000000425698 <_Dmain>:
425698: 55 push %rbp
425699: 48 8b ec mov %rsp,%rbp
42569c: 48 83 ec 18 sub $0x18,%rsp
4256a0: 53 push %rbx
4256a1: b0 ff mov $0xff,%al
4256a3: b1 ff mov $0xff,%cl
4256a5: 88 4d f8 mov %cl,-0x8(%rbp)
4256a8: ba ff ff ff ff mov $0xffffffff,%edx
4256ad: 89 55 fc mov %edx,-0x4(%rbp)
4256b0: 48 89 d3 mov %rdx,%rbx
4256b3: 48 8b 15 8e 69 02 00 mov 0x2698e(%rip),%rdx # 44c048 <_TMP0+0x8>
4256ba: 48 8b 35 7f 69 02 00 mov 0x2697f(%rip),%rsi # 44c040 <_TMP0>
4256c1: 48 89 c7 mov %rax,%rdi
4256c4: e8 9b 00 00 00 callq 425764 <void std.stdio.writefln!(immutable(char)[], ubyte).writefln(immutable(char)[], ubyte)>
4256c9: 48 8b 15 78 69 02 00 mov 0x26978(%rip),%rdx # 44c048 <_TMP0+0x8>
4256d0: 48 8b 35 69 69 02 00 mov 0x26969(%rip),%rsi # 44c040 <_TMP0>
4256d7: 40 8a 7d f8 mov -0x8(%rbp),%dil
4256db: e8 38 4f 00 00 callq 42a618 <void std.stdio.writefln!(immutable(char)[], byte).writefln(immutable(char)[], byte)>
4256e0: 48 8b 15 61 69 02 00 mov 0x26961(%rip),%rdx # 44c048 <_TMP0+0x8>
4256e7: 48 8b 35 52 69 02 00 mov 0x26952(%rip),%rsi # 44c040 <_TMP0>
4256ee: 8b 7d fc mov -0x4(%rbp),%edi
4256f1: e8 22 5a 00 00 callq 42b118 <void std.stdio.writefln!(immutable(char)[], uint).writefln(immutable(char)[], uint)>
4256f6: 48 8b 15 6b 69 02 00 mov 0x2696b(%rip),%rdx # 44c068 <_TMP1+0x8>
4256fd: 48 8b 35 5c 69 02 00 mov 0x2695c(%rip),%rsi # 44c060 <_TMP1>
425704: 48 89 df mov %rbx,%rdi
425707: e8 7c 64 00 00 callq 42bb88 <void std.stdio.writefln!(immutable(char)[], int).writefln(immutable(char)[], int)>
42570c: e8 7f ff ff ff callq 425690 <void test.marker()>
425711: 48 8b 0d 90 69 02 00 mov 0x26990(%rip),%rcx # 44c0a8 <_TMP2+0x8>
425718: 48 8b 05 81 69 02 00 mov 0x26981(%rip),%rax # 44c0a0 <_TMP2>
42571f: 48 89 c2 mov %rax,%rdx
425722: 48 be 08 00 00 00 00 movabs $0x8,%rsi
425729: 00 00 00
42572c: 48 89 df mov %rbx,%rdi
42572f: e8 ec 6d 00 00 callq 42c520 <void std.stdio.writefln!(immutable(char)[], ulong, ulong).writefln(immutable(char)[], ulong, ulong)>
425734: 48 8b 0d ad 69 02 00 mov 0x269ad(%rip),%rcx # 44c0e8 <_TMP3+0x8>
42573b: 48 8b 05 9e 69 02 00 mov 0x2699e(%rip),%rax # 44c0e0 <_TMP3>
425742: 48 89 c2 mov %rax,%rdx
425745: 48 be 08 00 00 00 00 movabs $0x8,%rsi
42574c: 00 00 00
42574f: 48 bf ff ff ff ff ff movabs $0x7fffffffffffffff,%rdi
425756: ff ff 7f
425759: e8 96 78 00 00 callq 42cff4 <void std.stdio.writefln!(immutable(char)[], ulong, long).writefln(immutable(char)[], ulong, long)>
42575e: 31 c0 xor %eax,%eax
425760: 5b pop %rbx
425761: c9 leaveq
425762: c3 retq
425763: 90 nop
I inserted the no-op marker() function so that the faulty code is easier to locate in the disassembly (I also filtered it through ddemangle so that identifiers are easier to read).
Worthy of note is that in the version=WithBug version, the movabs $0xffffffffffffffff,%rdi instruction prior to calling <void std.stdio.writefln!(immutable(char)[], ulong, ulong).writefln(immutable(char)[], ulong, ulong)> is missing. Instead, it copies the value from %rbx, but earlier, near the top of the function, %rbx got its value from %rdx, but %rdx was never set in its entirety. Instead, we have:
4256a8: ba ff ff ff ff mov $0xffffffff,%edx
4256ad: 89 55 fc ... (irrelevant)
4256b0: 48 89 d3 mov %rdx,%rbx
Looks like the codegen is wrongly assuming that the first immediate value, $0xffffffff, is 64-bit, whereas it's only 32-bit. So only the lower bits of %rdx are set. Hence the truncated value of ulong.max later on, when this value is passed to writefln.
Comment #4 by safety0ff.bugz — 2013-10-03T10:40:04Z
Works for me with DMD64 2.063.2, I think fixing issue 9844 likely solved this one.
Comment #5 by safety0ff.bugz — 2013-10-04T20:48:36Z
*** This issue has been marked as a duplicate of issue 9844 ***