This is an archive of the discontinued LLVM Phabricator instance.

[libc++] [LIBCXX-DEBUG-FIXME] Constexpr char_traits::copy mustn't compare unrelated pointers.
ClosedPublic

Authored by Quuxplusone on Apr 30 2021, 4:50 PM.

Details

Summary
Now that __builtin_is_constant_evaluated() is present on all supported
compilers, we can use it to skip the UB-inducing assert in cases where
the computation might be happening at constexpr time.

Diff Detail

Event Timeline

Quuxplusone requested review of this revision.Apr 30 2021, 4:50 PM
Quuxplusone created this revision.
Herald added 1 blocking reviewer(s): Restricted Project. · View Herald TranscriptApr 30 2021, 4:50 PM

poke buildkite

ldionne requested changes to this revision.May 5 2021, 10:53 AM

We should be able to compare pointers with std::less to solve this problem. It won't work if you just start using std::less because our std::less is actually wrong, however that's another problem we need to solve. We shouldn't just remove this assertion and hide the problem. So:

  1. Fix std::less so that it's not UB to use it to compare unrelated pointers (will require having some sort of special contract with the compiler that std::less can do that -- this could be done with some sort of builtin).
  2. Fix the debug mode so that it allows comparing unrelated pointers with std::less (frankly I'm not sure what's the best way of doing that off the top of my head, but we can explore).
  3. Use std::less to implement those pointer comparisons.

WDYT?

This revision now requires changes to proceed.May 5 2021, 10:53 AM
Quuxplusone planned changes to this revision.May 5 2021, 4:34 PM

We should be able to compare pointers with std::less to solve this problem. [...]
(will require having some sort of special contract with the compiler that std::less can do that -- this could be done with some sort of builtin)

I agree that that's what WG21 seems to want vendors to do. But that requires coordinating a new pointer-comparison builtin with both Clang and GCC, which is (definitely a good idea but) far above my pay grade. I'm happy to abandon this PR and let someone-not-me pursue the builtin angle...

Discussed offline with @ldionne and decided to sit on this for now, with the intent that someone will pursue adding a builtin at least to Clang.

Quuxplusone edited the summary of this revision. (Show Details)
Quuxplusone added a reviewer: Mordante.

Now that __builtin_is_constant_evaluated() is present on all supported
compilers, we can use it to skip the UB-inducing assert in cases where
the computation might be happening at constexpr time.

@ldionne ping!

Mordante accepted this revision as: Mordante.Sep 15 2021, 11:07 AM

Nice to see more tests working in debug mode. LGTM!

libcxx/include/__string
268–270

WDYT about adding a short comment. // comparing unrelated pointers is invalid in a constexpr function?

libcxx/include/__string
268–270

Seems relatively harmless, but repetitive (do it in all 6 places, right?). And if anyone did wonder enough about why the if was there, they could always remove it and see what tests broke. So, I'm ambivalent, but can add the comment if someone else — @ldionne? — also thinks it's a good idea.
Nit: s/constexpr function/constant expression/ or maybe constexpr context (which is a phrase I use a lot but has no textual support in the standard AFAIK).

ldionne accepted this revision.Sep 20 2021, 10:25 AM
This revision is now accepted and ready to land.Sep 20 2021, 10:25 AM