From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1691 invoked by alias); 31 Dec 2014 16:25:11 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 1635 invoked by uid 48); 31 Dec 2014 16:25:04 -0000 From: "daniel.c.klauer at web dot de" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/64384] mingw-w64: stdcall function returning an aggregate is incompatible with MS ABI Date: Wed, 31 Dec 2014 16:25:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Version: 4.9.2 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: daniel.c.klauer at web dot de X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2014-12/txt/msg03001.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64384 --- Comment #5 from daniel.c.klauer at web dot de --- I also think that COM is supposed to be usable from C and C++, but it seems that here we have an exception to this rule. Let's examine asm generated by the ms compiler for calls to GetSize(), C and C++ versions respectively: C++: ID2D1HwndRenderTarget *hwndRenderTarget; D2D1_SIZE_F size; size = hwndRenderTarget->GetSize(); Code generated by cl: lea edx, DWORD PTR $T76363[ebp] # temp var for the result push edx # hidden pointer arg [...push THIS arg and get function pointer from vtable into eax...] call eax # returns pointer to temp var in eax mov ecx, DWORD PTR [eax] # reading result from temp var, 1st member mov edx, DWORD PTR [eax+4] # 2nd member of D2D1_SIZE_F mov DWORD PTR _size$[ebp], ecx mov DWORD PTR _size$[ebp+4], edx C: ID2D1HwndRenderTarget *hwndRenderTarget; D2D1_SIZE_F size; size = hwndRenderTarget->lpVtbl->Base.GetSize( (ID2D1RenderTarget *)hwndRenderTarget); Code generated by cl: [...push THIS arg and get function pointer into ecx...] call ecx mov DWORD PTR _size$[ebp], eax # reading result from edx:eax registers mov DWORD PTR _size$[ebp+4], edx The C++ version works well; the C version crashes at the GetSize() call. They're using incompatible aggregate return mechanisms (despite stdcall), but since the d2d1.dll (which, I assume, implements this interface) will only use one of the two mechanisms, the other won't work. Obviously d2d1.dll uses the C++ version because that's what works. Assuming this is part of MS ABI and not a bug in the MS compiler, then the problem with gcc is that its aggregate return for C++ methods differs from MS ABI (though it's correct for normal C-style functions).