Bug 21515 – extern(C) and extern(C++) returns creal in wrong order
Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
Linux
Creation time
2020-12-29T22:18:39Z
Last change time
2021-01-25T01:07:36Z
Keywords
wrong-code
Assigned to
No Owner
Creator
Iain Buclaw
Comments
Comment #0 by ibuclaw — 2020-12-29T22:18:39Z
This program fails.
---
extern "C" _Complex long double ctwol() { return 1+0Li; }
extern(C) creal ctwol(); // Because extern(C++) ICE's
void main()
{
auto a = ctwol();
assert(a.re == 2 && a.im == 0);
}
---
DMD generates:
callq d <_Dmain+0xd>
fstpt -0x10(%rbp)
fstpt -0x20(%rbp)
When it should instead do:
callq d <_Dmain+0xd>
fstpt -0x20(%rbp)
fstpt -0x10(%rbp)
Comment #1 by ibuclaw — 2020-12-29T22:19:29Z
(In reply to Iain Buclaw from comment #0)
> This program fails.
> ---
> extern "C" _Complex long double ctwol() { return 1+0Li; }
>
Oops, that should be 2+0Li. :-)
Comment #2 by dlang-bot — 2020-12-30T01:07:15Z
@ibuclaw created dlang/dmd pull request #12073 "Attempt fixing Issue 21515 extern(C) and extern(C++) returns creal in wrong order" mentioning this issue:
- Attempt fixing Issue 21515
https://github.com/dlang/dmd/pull/12073
Comment #3 by dlang-bot — 2021-01-25T01:07:36Z
dlang/dmd pull request #12073 "fix Issue 21515 extern(C) and extern(C++) returns creal in wrong order" was merged into master:
- 7e445d61509f97de902528b9c68bd5d247563e14 by Iain Buclaw:
fix Issue 21515 - extern(C) and extern(C++) returns creal in wrong order
In loadComplex and complex_eq87, the real part of x87 complex numbers
are pushed to the FPU register stack first (ST1), then the imaginary
part (ST0). However, on the I64 ABI, real part is instead returned in
ST0 and the imaginary part in ST1. To handle this, FXCH is inserted
before returning from, and after calling a complex long double function.
https://github.com/dlang/dmd/pull/12073