[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2018-02-24 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #18 from Walter Bright  ---
Temporary workaround

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2018-02-24 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #17 from Walter Bright  ---
On Linux x86, given the code:

  struct S { };
  int test(S s, int a) { return a; }

g++ produces:
mov EAX,8[ESP]
ret

while clang++ produces:

mov EAX,4[ESP]
ret

This is with optimization on. With it off, the same problem.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2018-02-24 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #16 from Walter Bright  ---
With the upgrade to FreeBSD 11, this is now happening on 32 bit FreeBSD.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2018-02-24 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #15 from Walter Bright  ---
*** Issue 18514 has been marked as a duplicate of this issue. ***

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2018-02-24 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

Walter Bright  changed:

   What|Removed |Added

   Keywords||C++

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2017-05-20 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #14 from Jacob Carlborg  ---
(In reply to Joakim from comment #13)

> dmd and ldc work with the gcc approach, but not clang's.

Clang is the native compiler on macOS, so I would say that we should go with
whatever Clang is doing.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2017-05-20 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #13 from Joakim  ---
I spent a little time looking into this again.  The issue now appears to only
be reproducible if clang compiles without any optimizations, which is what the
dmd testsuite does.  When run without any optimizations, clang assumes the
empty struct will not be passed in and only passes along the first six
arguments, ie arg0 through arg5.  Since arg6 is not passed back to check13956,
it asserts.

These issues only crop up on 32-bit arches, including ARM32, as kinke noted
last summer, which explains why Jacob hasn't seen this on 64-bit OS X.

Here is the disassembly for what clang produces on linux/x86 without
optimization:

 <_Z9func139566S13956ii>:
   0:   55  push   %ebp
   1:   89 e5   mov%esp,%ebp
   3:   53  push   %ebx
   4:   57  push   %edi
   5:   56  push   %esi
   6:   83 ec 3csub$0x3c,%esp
   9:   8b 45 1cmov0x1c(%ebp),%eax
   c:   8b 4d 18mov0x18(%ebp),%ecx
   f:   8b 55 14mov0x14(%ebp),%edx
  12:   8b 75 10mov0x10(%ebp),%esi
  15:   8b 7d 0cmov0xc(%ebp),%edi
  18:   8b 5d 08mov0x8(%ebp),%ebx
  1b:   89 5d ecmov%ebx,-0x14(%ebp)
  1e:   89 7d e8mov%edi,-0x18(%ebp)
  21:   89 75 e4mov%esi,-0x1c(%ebp)
  24:   89 55 e0mov%edx,-0x20(%ebp)
  27:   89 4d dcmov%ecx,-0x24(%ebp)
  2a:   89 45 d8mov%eax,-0x28(%ebp)
  2d:   8b 45 ecmov-0x14(%ebp),%eax
  30:   8b 4d e8mov-0x18(%ebp),%ecx
  33:   8b 55 e4mov-0x1c(%ebp),%edx
  36:   8b 75 e0mov-0x20(%ebp),%esi
  39:   8b 7d dcmov-0x24(%ebp),%edi
  3c:   8b 5d d8mov-0x28(%ebp),%ebx
  3f:   89 04 24mov%eax,(%esp)
  42:   89 4c 24 04 mov%ecx,0x4(%esp)
  46:   89 54 24 08 mov%edx,0x8(%esp)
  4a:   89 74 24 0c mov%esi,0xc(%esp)
  4e:   89 7c 24 10 mov%edi,0x10(%esp)
  52:   89 5c 24 14 mov%ebx,0x14(%esp)
  56:   e8 fc ff ff ff  call   57 <_Z9func139566S13956ii+0x57>
  57: R_386_PC32  _Z10check139566S13956ii
  5b:   83 c4 3cadd$0x3c,%esp
  5e:   5e  pop%esi
  5f:   5f  pop%edi
  60:   5b  pop%ebx
  61:   5d  pop%ebp
  62:   c3  ret

Conversely, here's what gcc produces:

 <_Z9func139566S13956ii>:
   0:   55  push   %ebp
   1:   89 e5   mov%esp,%ebp
   3:   83 ec 08sub$0x8,%esp
   6:   83 ec 04sub$0x4,%esp
   9:   ff 75 20pushl  0x20(%ebp)
   c:   ff 75 1cpushl  0x1c(%ebp)
   f:   ff 75 18pushl  0x18(%ebp)
  12:   ff 75 14pushl  0x14(%ebp)
  15:   ff 75 10pushl  0x10(%ebp)
  18:   ff 75 0cpushl  0xc(%ebp)
  1b:   50  push   %eax
  1c:   e8 fc ff ff ff  call   1d <_Z9func139566S13956ii+0x1d>
1d: R_386_PC32  _Z10check139566S13956ii
  21:   83 c4 20add$0x20,%esp
  24:   90  nop
  25:   c9  leave
  26:   c3  ret

When clang is run with optimization, it just calls the D function directly,
which happens to avoid the problem, though likely the underlying assumption is
still there:

 <_Z9func139566S13956ii>:
   0:   e9 fc ff ff ff  jmp1 <_Z9func139566S13956ii+0x1>
1: R_386_PC32   _Z10check139566S13956ii

I'm not sure if clang with optimization always did this: just don't remember if
I tried it before, maybe not.

As kinke said, clang and gcc assume different argument passing for empty
structs on 32-bit arches, confirmed for both x86 and ARM32.  dmd and ldc work
with the gcc approach, but not clang's.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-09-19 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #12 from Jacob Carlborg  ---
I've been using Clang for ages now and it passes the test suite, at least for
64bit. I'm running Apple LLVM version 7.3.0 (clang-703.0.31)

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-09-18 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #11 from Brad Roberts  ---
I haven't tested building with clang on osx in ages.  If it's at the point of
passing tests then I'd be happy to convert any/all of the three testers back to
their default compiler.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-09-13 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #10 from Joakim  ---
I ran into this on Android/ARM too, with ldc.  As the linked ldc comment and
Jacob note, this is an incompatibility in the way clang and gcc work with empty
structs on every platform, whether Linux/x86 or Android/ARM.  This test and the
auto-tester simply use gcc on every other tested platform, while clang is the
system compiler on OS X now.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-09-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #9 from Jacob Carlborg  ---
(In reply to kinke from comment #4)
> clang doesn't pass empty structs at all for 32-bit, while GCC does. We have
> such a special case in LDC too for 32-bit OSX, where we assume clang, but
> not for 32-bit Linux, where we assume GCC. See
> https://github.com/ldc-developers/ldc/blob/master/gen/abi-x86.cpp#L214.

Clang claims to be compatible with GCC. If there's a case when it's not
compatible, it might be a bug in Clang.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-09-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #8 from Jacob Carlborg  ---
(In reply to Martin Nowak from comment #7)

> We also have that issue with GCC5's C++ ABI change
> (http://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/), so
> detecting the actual compiler might be helpful as well.

As far as I understand, it's configurable if that ABI should be used or not. So
just detecting the compiler is not enough, unless we decide to only support one
ABI.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-09-11 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

Martin Nowak  changed:

   What|Removed |Added

 CC||bra...@puremagic.com

--- Comment #7 from Martin Nowak  ---
(In reply to kinke from comment #4)
> clang doesn't pass empty structs at all for 32-bit, while GCC does. We have
> such a special case in LDC too for 32-bit OSX, where we assume clang, but
> not for 32-bit Linux, where we assume GCC. See
> https://github.com/ldc-developers/ldc/blob/master/gen/abi-x86.cpp#L214.

Thanks, assuming clang by default on OSX indeed seems like a reasonable
solution.
We also have that issue with GCC5's C++ ABI change
(http://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/), so
detecting the actual compiler might be helpful as well.

(In reply to Jacob Carlborg from comment #6)
> There's a long time since Apple switched to Clang. GCC is dead on Apple
> platforms. I've mentioned this several times that the autotester should
> switch to Clang.

Yes, would be good if we updated the auto-testers to use clang @Brad.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-07-27 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

Jacob Carlborg  changed:

   What|Removed |Added

 CC||d...@me.com

--- Comment #6 from Jacob Carlborg  ---
(In reply to Walter Bright from comment #5)
> So the regression is that Apple switched to clang, and clang does things
> differently?

There's a long time since Apple switched to Clang. GCC is dead on Apple
platforms. I've mentioned this several times that the autotester should switch
to Clang.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-07-26 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

Walter Bright  changed:

   What|Removed |Added

 CC||bugzi...@digitalmars.com

--- Comment #5 from Walter Bright  ---
So the regression is that Apple switched to clang, and clang does things
differently?

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-07-24 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

ki...@gmx.net changed:

   What|Removed |Added

 CC||ki...@gmx.net

--- Comment #4 from ki...@gmx.net ---
clang doesn't pass empty structs at all for 32-bit, while GCC does. We have
such a special case in LDC too for 32-bit OSX, where we assume clang, but not
for 32-bit Linux, where we assume GCC. See
https://github.com/ldc-developers/ldc/blob/master/gen/abi-x86.cpp#L214.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-07-24 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

Martin Nowak  changed:

   What|Removed |Added

   Severity|normal  |regression

--- Comment #3 from Martin Nowak  ---
Now this also fails on the OSX-64/32 test on the auto-tester, so this might
actually be a relevant regression.

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-07-07 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

--- Comment #2 from Martin Nowak  ---
Also fails with a single int argument.

cat > cpp.cc << CODE
#include 
struct S13956
{
};

void check13956(S13956 arg0, int arg1);

void func13956(S13956 arg0, int arg1)
{
printf("C %d\n", arg1);
check13956(arg0, arg1);
}
CODE

cat > bug.d << CODE
import core.stdc.stdio;
struct S13956
{
}

extern(C++) void func13956(S13956 arg0, int arg1)
{
check13956(arg0, arg1);
}

extern(C++) void check13956(S13956 arg0, int arg1)
{
printf("C %d\n", arg1);
assert(arg0 == S13956());
assert(arg1 == 1);
}

void main()
{
func13956(S13956(), 1);
}
CODE

c++ -m32 -c cpp.cc
dmd -m32 cpp.o -run bug

--


[Issue 16243] wrong C++ argument passing with empty struct and 6 integers

2016-07-06 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16243

Martin Nowak  changed:

   What|Removed |Added

Summary|wrong argument passed with  |wrong C++ argument passing
   |empty struct and 6 integers |with empty struct and 6
   ||integers

--- Comment #1 from Martin Nowak  ---
Complete test case, also requires a C++ roundtrip. C++ compiler is.

Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.2.0
Thread model: posix

cat > cpp.cc << CODE
struct S13956
{
};

void check13956(S13956 arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
int arg6);

void func13956(S13956 arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
int arg6)
{
check13956(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
}
CODE

cat > bug.d << CODE
struct S13956
{
}

extern(C++) void func13956(S13956 arg0, int arg1, int arg2, int arg3, int arg4,
int arg5, int arg6)
{
check13956(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
}

extern(C++) void check13956(S13956 arg0, int arg1, int arg2, int arg3, int
arg4, int arg5, int arg6)
{
assert(arg0 == S13956());
assert(arg1 == 1);
assert(arg2 == 2);
assert(arg3 == 3);
assert(arg4 == 4);
assert(arg5 == 5);
assert(arg6 == 6); // fails on OSX 32-bit
}

void main()
{
func13956(S13956(), 1, 2, 3, 4, 5, 6);
}
CODE

c++ -m32 -c cpp.cc
dmd -m32 cpp.o -run bug

--