[Issue 20148] void initializated bool can be both true and false
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Fri Jun 5 23:31:09 UTC 2020
https://issues.dlang.org/show_bug.cgi?id=20148
hsteoh at quickfur.ath.cx changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |hsteoh at quickfur.ath.cx
--- Comment #2 from hsteoh at quickfur.ath.cx ---
There's more to it than a hole in @safe. Look at the disassembly below, there
seems to be a codegen bug as well:
-------------------
000000000003f698 <_Dmain>:
3f698: 55 push %rbp
3f699: 48 8b ec mov %rsp,%rbp
3f69c: 48 83 ec 10 sub $0x10,%rsp
3f6a0: 40 8a 7d f8 mov -0x8(%rbp),%dil
3f6a4: e8 07 00 00 00 callq 3f6b0 <@trusted void
test.f(bool)>
3f6a9: 31 c0 xor %eax,%eax
3f6ab: c9 leaveq
3f6ac: c3 retq
3f6ad: 00 00 add %al,(%rax)
...
000000000003f6b0 <@trusted void test.f(bool)>:
3f6b0: 55 push %rbp
3f6b1: 48 8b ec mov %rsp,%rbp
3f6b4: 48 83 ec 20 sub $0x20,%rsp
3f6b8: 89 7d f8 mov %edi,-0x8(%rbp)
3f6bb: c6 45 e8 00 movb $0x0,-0x18(%rbp)
3f6bf: 40 80 7d f8 00 rex cmpb $0x0,-0x8(%rbp)
3f6c4: 74 06 je 3f6cc <@trusted void
test.f(bool)+0x1c>
3f6c6: 48 8d 45 e8 lea -0x18(%rbp),%rax
3f6ca: eb 0a jmp 3f6d6 <@trusted void
test.f(bool)+0x26>
3f6cc: bf 01 00 00 00 mov $0x1,%edi
3f6d1: e8 9a fc ff ff callq 3f370 <malloc at plt>
3f6d6: 48 89 45 f0 mov %rax,-0x10(%rbp)
3f6da: 8a 4d f8 mov -0x8(%rbp),%cl
3f6dd: 80 f1 01 xor $0x1,%cl
3f6e0: 74 09 je 3f6eb <@trusted void
test.f(bool)+0x3b>
3f6e2: 48 8b 7d f0 mov -0x10(%rbp),%rdi
3f6e6: e8 65 f9 ff ff callq 3f050 <free at plt>
3f6eb: c9 leaveq
3f6ec: c3 retq
---------------
In main(), the value of -0x8(%rbp), apparently where main.b is stored, is
loaded into the lower register %dil. But in f(), the value of the entire
register %edi is stored in a local variable (coincidentally -0x8(%rbp), but
points to a different place because this is now the local scope of the callee).
Then a few instructions down this local variable is tested for having all 0's
in its value: even though only the lower part of the register was actually
loaded in main!
Then after the if-statement, the (lower byte of the) local variable -0x8(%rbp)
is loaded into %cl and compared against a literal 1.
Even though technically this codegen works if b is either 0 or 1, it seems
inconsistent at best (why compare the entire 32-bit value to 0 when checking
for false, but only the lower byte when checking for true?), and in this case
outright wrong when b is uninitialized and therefore can have any random
garbage value other than 0 or 1.
--
More information about the Digitalmars-d-bugs
mailing list