-
Notifications
You must be signed in to change notification settings - Fork 10.5k
stdlib: remove some static assertions which may not hold #21606
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
Conversation
cc @mikeash |
e0e3b49
to
377a5e8
Compare
@swift-ci please test Linux platform |
Build failed |
I don't think we can remove these assertions. We rely on a HeapObject coming out of calloc ready to go. |
@jrose-apple - that is not a guarantee that the C++ standard makes. The |
From the random copy of C++11 that turned up in a search:
Which I think means it has to have the same representation as the integer type, and not do any initialization. I'm bad at standardese though so draw your own conclusions. |
Yes, it has the same representation, but the constructor is needed to initialize it to 0 (otherwise it is in an indeterminate state). The zero-ing of the member is sufficient to make it fail the trivial constructability test. See LWG Issue 2334. LWG P0883 is designed to address this which will make the |
So we can still put them in constant sections because of the newly-added |
@jrose-apple - hmm, perhaps you can file a radar for that? I think that this would be something that Apple might want to track more closely (but, this was found by building with the next version of the C++ runtime from Microsoft which does actually implement parts of the future specification), so this will become a problem for everyone. |
@mikeash, what do you think? |
It looks like we don't actually rely on the memory being zero-filled at allocation as I was thinking. We call through to That initialization has an interesting comment:
Can we find a way to use placement new without penalty? Seems like that would be the best for everything. |
@mikeash - yes and no. It is "removable" by switching to C++17. As of C++17, a null pointer to the placement new is UB, which means that the |
@mikeash - until we can move to C++17, what do you think is the best way to move forward here? |
@mikeash - ping |
Sorry to leave you hanging! I don't want to introduce an unnecessary NULL check. If placement new means we have to have the check for now, can we use placement new when compiling with VC++ and keep the existing version for other compilers? Alternately, is it possible to avoid the NULL check with an annotation to inform the compiler that the pointer is definitely not ever NULL? Either one would be good by me. |
I'm happy with a C++17/Windows path through this codepath. Interestingly enough, I do not see a null pointer check even with C++14:
|
Maybe the compiler has already figured out that it can't be NULL? Let me know and send me a diff if you'd like me to try with clang and see if it produces good code. |
377a5e8
to
c2af8f9
Compare
@mikeash - uploaded a new version of the change that enables it under C++17 and Windows, I'll double check this on Linux as well. |
Build failed |
I'll try the placement new path on Mac and see how it does. If we can be confident that it'll generate good code then maybe we can just use that everywhere. |
@mikeash - please do, since I just ran this on Linux (with some "hacks" - namely, added
|
Here's what I get with placement new:
Looks great! Seems like we might as well use it everywhere now. I guess that comment must be obsolete. |
Build failed |
Awesome! I'll upload a new version with that enabled globally! |
The assertions here are based around the idea that `std::atomic` is trivially constructible which is not a guarantee that the standard fully provides. The default initialization of the `std::atomic` type may leave it in an undetermined state. These were caught using the Visual C++ preview runtime. Ideally, the object constructor would use a placement new operator. However, prior to C++17, the C++ standard mandated that there be a NULL pointer check in the placement new operator. This is something which is no longer the case with C++17. Switch to the placement new operator for C++17 and newer and enable that codepath for Windows as well (which seemingly elides the null-pointer check with clang-cl).
c2af8f9
to
0983ea6
Compare
@swift-ci please test |
Build failed |
Woohoo! |
@mikeash - okay to merge? |
Go for it! |
These are based around the idea that
std::atomic
is triviallyconstructible, which is not a guarantee that the standard fully
provides. The default initialization of the
std::atomic
typemay leave it in an undetermined state. These were caught using
the Visual C++ preview runtime.
Replace this paragraph with a description of your changes and rationale. Provide links to external references/discussions if appropriate.
Resolves SR-NNNN.