Comment #0 by verylonglogin.reg — 2011-05-09T23:46:44Z
Created attachment 966
Problem curious test case
Simple program:
void main()
{
void f() { }
void* t;
t = (&f).ptr;
//t = (&f).funcptr; //Uncommented: Error: &f is not an lvalue
}
First, look at lines 00402019 and 0040201E in disassembled main (dmd 1.067):
void main()
00402010 enter 4,0
void* t;
00402014 xor eax,eax
00402016 mov dword ptr [t],eax
t = (&f).ptr;
00402019 mov ecx,offset main@main@f (402028h)
0040201E mov dword ptr [t],eax
00402021 xor eax,eax
//t = (&f).funcptr; //Uncommented: Error: &f is not an lvalue
}
00402023 leave
00402024 ret
00402025 int 3
00402026 int 3
00402027 int 3
{
void f() { }
00402028 enter 4,0
0040202C mov dword ptr [ebp-4],eax
0040202F leave
00402030 ret
Second, why "&f is not an lvalue" error occurs for "(&f).funcptr"? Maybe, I
don't understand something?
Third, look at curiousTest.d attachment - it fails only if both asserts are
uncommented.
Comment #1 by clugdbug — 2011-12-20T23:28:04Z
More direct test case:
void main()
{
void f() { }
void* t1 = (&f).ptr;
void* t2 = (&f).ptr;
assert(t1 == t2);
}
The fac that (&f).funcptr fails to compile is a separate though closely related bug.
Comment #2 by yebblies — 2012-01-18T19:10:45Z
(In reply to comment #0)
> Second, why "&f is not an lvalue" error occurs for "(&f).funcptr"? Maybe, I
> don't understand something?
iirc this fails because dmd rewrites dg.funcptr as *(cast(void**)(&dg)+1), which naturally doesn't work on an rvalue. The way to fix this is to rewrite it as cast(void*)(cast(uint<64/128>)dg >> <32/64>), the same way array length is accessed.
Comment #3 by dlang-bugzilla — 2017-06-26T11:57:36Z
I believe this was fixed in https://github.com/dlang/dmd/pull/3181 - at least, the program in comment 2 stops failing after that change. Please reopen otherwise.