Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue 14086 - Invalid extern C++ name for constructor #8265

Merged
merged 1 commit into from
May 21, 2018

Conversation

TurkeyMan
Copy link
Contributor

@TurkeyMan TurkeyMan commented May 20, 2018

Destructor mangles correctly, but constructor does not.
This has wasted a lot of time with people trying to understand link problems with extern(C++).

As with the dtor, the ABI appears to be perfectly compatible... so, mangling correctly.
Also, fixed the virtual-ness mangling of the destructor. Windows dtor mangling only half-worked.

@TurkeyMan TurkeyMan requested a review from ibuclaw as a code owner May 20, 2018 02:45
@dlang-bot
Copy link
Contributor

dlang-bot commented May 20, 2018

Thanks for your pull request and interest in making D better, @TurkeyMan! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the annotated coverage diff directly on GitHub with CodeCov's browser extension
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Auto-close Bugzilla Severity Description
14086 enhancement Invalid extern C++ name for constructor / destructor

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub fetch digger
dub run digger -- build "master + dmd#8265"

@JinShil
Copy link
Contributor

JinShil commented May 20, 2018

Please rename the commit messaged to ensure the dlang-bot establishes a relationship between this PR and the bugzilla issue. I usually make the PR title and commit message the same.

@JinShil
Copy link
Contributor

JinShil commented May 20, 2018

Adding the "Vision" label as this is congruent with item 4 of Vision 2018H1

  1. Improve interoperability with other languages: Finishing -betterC should improve incremental migration of C and C++.

@JinShil JinShil added the Vision Vision Plan https://wiki.dlang.org/Vision/2018H1 label May 20, 2018
@TurkeyMan
Copy link
Contributor Author

It's in the PR header... that is included in the comment when pulled.
dbot will see that won't he?

@TurkeyMan
Copy link
Contributor Author

Why is DAutoTest red? I had this problem last PR too...

@rainers
Copy link
Member

rainers commented May 20, 2018

It complains about your terse changelog entry:

object.Exception@../tools/changed.d(216): Changelog entries should consist of one title line, a blank separator line, and a description.

@kinke
Copy link
Contributor

kinke commented May 20, 2018

When calling an extern(C++) ctor implemented in D from C++, one needs to be aware that the ctor assumes the instance is pre-initialized with T.init and may not initialize all fields, so one may end up with garbage.

Wrt. destruction, the ABIs diverge when it comes to destructing by-value arguments - for C++, the caller destructs it (and passes a ref to the callee), while D compilers move the argument and let the callee destruct the param. This also happens when using extern(C++) for the D code, with DMD, LDC and GDC, so D/C++ interop for non-POD values passed by value is broken on most platforms anyway. On Win64 (where D compilers pass non-PODs by ref), when passing a non-POD by value from C++ to a D function, I expect a double-destruction (and D's callee doesn't reset it to T.init after the first destruction), and no destruction at all when calling a C++ function from D.
Edit: Nope, MSVC++ on Win64 seems to do it exactly like D (tested with LDC), letting the callee destruct it. It's still broken on POSIX systems, at least for x86_64.

@TurkeyMan
Copy link
Contributor Author

@kinke I've been desperately searching for this document!!
Where is all the very important information documented?
I can't even find docs that talk about __xdtor, or something so simple as the vtable layout! >_<

It's really hard to start to address these issues with no information available.

@TurkeyMan
Copy link
Contributor Author

Next port of call is to attempt to make the behaviours of extern(C++) stuff precisely match C++.

@kinke
Copy link
Contributor

kinke commented May 20, 2018

Where is all the very important information documented?

At least for MSVC++, I didn't find anything official either (wrt. C++ ABI; the platform/C ABI is documented); I just 'reverse-engineered' the ABI details by studying the C++ assembly for various test structs. I did so recently for DIP 1014 (postMove hook; => ldc-developers/ldc#2702), that's how I know about x86_64 POSIX, and today's MSVC tests led to ldc-developers/ldc#2706. ;)

@TurkeyMan
Copy link
Contributor Author

But for D? The details for D should be published somewhere.

@TurkeyMan
Copy link
Contributor Author

@kinke Are you on IM? I have a zillion questions I need quick answers to :/

@jacob-carlborg
Copy link
Contributor

It’s usually quite difficult to find documentation for these kinds of things. You usually find out when implementing a compiler.

@WalterBright
Copy link
Member

Nope, MSVC++ on Win64 seems to do it exactly like D (tested with LDC), letting the callee destruct it. It's still broken on POSIX systems, at least for x86_64.

No surprise there. The original VC++ was based on the ABI used by Zortech C++ :-)

We sold a lot of Zortech C++ compilers into Microsoft before they started implementing C++. The COM ABI is directly the ABI used by ZTC++ for virtual functions.

@kinke is quite right that not only is there no document for this, when such documents exist they tend to be all lies. The only reliable way is to write test cases, compile them, and examine the object file.

BTW, I didn't realize that Posix does these things differently.

Copy link
Member

@WalterBright WalterBright left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving despite the problems @kinke reported. At least matching the mangling is a good first step.

@TurkeyMan
Copy link
Contributor Author

Thanks. My next struggle is trying to work out how __xdtor is fabricated, and mangle THAT symbol as C++ dtor instead of the explicit dtor. __xdtor does what C++ expects.

@kinke
Copy link
Contributor

kinke commented May 20, 2018

@TurkeyMan: That's here. __xdtor seems to be an alias for __aggrDtor is just an alias.

@TurkeyMan
Copy link
Contributor Author

TurkeyMan commented May 20, 2018

Huh... I don't understand why semaphore says it failed?
It passed just before. I only pushed to update the changelog.

@TurkeyMan
Copy link
Contributor Author

Okay, seriously... after how ever many hours waiting for the CI to build, then it fails.
This CI situation is really not great.

@dlang-bot dlang-bot merged commit da4c5e1 into dlang:master May 21, 2018
@TurkeyMan TurkeyMan deleted the ctor_mangle branch May 21, 2018 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-merge Enhancement Vision Vision Plan https://wiki.dlang.org/Vision/2018H1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants