Page MenuHomePhabricator

[libc++] Consistently replace `::new(__p) T` with `::new ((void*)__p) T`. NFCI
ClosedPublic

Authored by Quuxplusone on Dec 11 2020, 6:08 PM.

Details

Summary

Everywhere, normalize the whitespace to ::new (EXPR) T.
Everywhere, normalize the spelling of the cast to (void*)EXPR.

Without the cast to (void*), the expression triggers ADL on GCC.
(I think this is a GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98249)
Even if it doesn't trigger ADL, it still seems incorrect to use any argument that's not exactly (void*) because that opens the possibility of overload resolution picking a user-defined overload of operator new, which would be wrong.

(I admit this is nitpicky and code-churny, but it's also cleanup. I'm particularly interested to see if buildkite will tell me exactly why __voidify was needed for the constexpr construct_at stuff; that's the one slightly scary change hiding in this PR.)

Diff Detail

Event Timeline

Quuxplusone created this revision.Dec 11 2020, 6:08 PM
Quuxplusone requested review of this revision.Dec 11 2020, 6:08 PM
Herald added a reviewer: Restricted Project. · View Herald TranscriptDec 11 2020, 6:08 PM
curdeius accepted this revision.Dec 13 2020, 6:03 AM
curdeius added a subscriber: curdeius.

LGTM. This __voidify looks really strange indeed. Blame shows that it was added in https://github.com/llvm/llvm-project/commit/0724f8bf47f8cb073d41e2750d45d5b05e66bf0b by @ldionne.

LGTM. This __voidify looks really strange indeed. Blame shows that it was added in https://github.com/llvm/llvm-project/commit/0724f8bf47f8cb073d41e2750d45d5b05e66bf0b by @ldionne.

TBH, I just implemented it in the most naive way possible, based on http://eel.is/c++draft/specialized.algorithms#general-4.

I'm not sure why we first cast to const volatile void* and then use remove_const, instead of just casting to void volatile*.

ldionne accepted this revision.Dec 14 2020, 8:02 AM

This seems reasonable to me.

This revision is now accepted and ready to land.Dec 14 2020, 8:02 AM
zoecarver added inline comments.
libcxx/include/__functional_03
129

Nit: would be better to make these static_casts IMHO.

129

Sorry, didn't realize this already landed. No need to change it.

Quuxplusone marked 2 inline comments as done.Dec 14 2020, 2:02 PM
Quuxplusone added inline comments.
libcxx/include/__functional_03
129

No worries, I would have argued anyway. ;)
My goal is to be consistent on something that we can cut and paste everywhere, so I would want to use static_cast here only if you are willing to use static_cast everywhere.

For this spot in particular, are you worried that the allocator's pointers might be fancy? If that's the issue, then I think we actually need something like ::new ((void*)_VSTD::addressof(*__hold.get())) __func(...). The kind of cast isn't the problem; it's that no such conversion might exist at all. (And my recent patch-series has taught me that *__hold.get() avoids ADL when *__hold would trigger it. Gross, right?)

zoecarver added inline comments.Dec 14 2020, 2:47 PM
libcxx/include/__functional_03
128

We could use @ldionne's new __allocation_guard here :)

129

My point was exactly that, I'd prefer to see static_cast everywhere rather than a C-style cast. But that's mostly just a stylistic thing. I don't have any worry about a cast to void* failing at compile time. (Which is why it was a nit.)

I was moving too quickly when I wrote this comment ;) I didn't carefully read where I made the suggestion. I think you're right, we really should be doing _VSTD::addressof(*__hold.get()) in most places. That's what we do for allocate_shared, for example. But that's a different patch...