https://issues.dlang.org/show_bug.cgi?id=16243
--- Comment #13 from Joakim <db...@joakim.fea.st> --- 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: 00000000 <_Z9func139566S13956iiiiii>: 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 3c sub $0x3c,%esp 9: 8b 45 1c mov 0x1c(%ebp),%eax c: 8b 4d 18 mov 0x18(%ebp),%ecx f: 8b 55 14 mov 0x14(%ebp),%edx 12: 8b 75 10 mov 0x10(%ebp),%esi 15: 8b 7d 0c mov 0xc(%ebp),%edi 18: 8b 5d 08 mov 0x8(%ebp),%ebx 1b: 89 5d ec mov %ebx,-0x14(%ebp) 1e: 89 7d e8 mov %edi,-0x18(%ebp) 21: 89 75 e4 mov %esi,-0x1c(%ebp) 24: 89 55 e0 mov %edx,-0x20(%ebp) 27: 89 4d dc mov %ecx,-0x24(%ebp) 2a: 89 45 d8 mov %eax,-0x28(%ebp) 2d: 8b 45 ec mov -0x14(%ebp),%eax 30: 8b 4d e8 mov -0x18(%ebp),%ecx 33: 8b 55 e4 mov -0x1c(%ebp),%edx 36: 8b 75 e0 mov -0x20(%ebp),%esi 39: 8b 7d dc mov -0x24(%ebp),%edi 3c: 8b 5d d8 mov -0x28(%ebp),%ebx 3f: 89 04 24 mov %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 <_Z9func139566S13956iiiiii+0x57> 57: R_386_PC32 _Z10check139566S13956iiiiii 5b: 83 c4 3c add $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: 00000000 <_Z9func139566S13956iiiiii>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 ec 08 sub $0x8,%esp 6: 83 ec 04 sub $0x4,%esp 9: ff 75 20 pushl 0x20(%ebp) c: ff 75 1c pushl 0x1c(%ebp) f: ff 75 18 pushl 0x18(%ebp) 12: ff 75 14 pushl 0x14(%ebp) 15: ff 75 10 pushl 0x10(%ebp) 18: ff 75 0c pushl 0xc(%ebp) 1b: 50 push %eax 1c: e8 fc ff ff ff call 1d <_Z9func139566S13956iiiiii+0x1d> 1d: R_386_PC32 _Z10check139566S13956iiiiii 21: 83 c4 20 add $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: 00000000 <_Z9func139566S13956iiiiii>: 0: e9 fc ff ff ff jmp 1 <_Z9func139566S13956iiiiii+0x1> 1: R_386_PC32 _Z10check139566S13956iiiiii 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. --