D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 21515 - extern(C) and extern(C++) returns creal in wrong order
Summary: extern(C) and extern(C++) returns creal in wrong order
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All Linux
: P1 major
Assignee: No Owner
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2020-12-29 22:18 UTC by Iain Buclaw
Modified: 2021-01-25 01:07 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Iain Buclaw 2020-12-29 22:18:39 UTC
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 Iain Buclaw 2020-12-29 22:19:29 UTC
(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 Dlang Bot 2020-12-30 01:07:15 UTC
@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 Dlang Bot 2021-01-25 01:07:36 UTC
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