This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Add GCC workaround in std::char_traits<char>::length()
ClosedPublic

Authored by philnik on Dec 15 2021, 4:14 AM.

Details

Summary

GCC currently does not allow __builtin_strlen() during constant evaluation. This PR adds a workaround in std::char_traits<char>::length()

Diff Detail

Event Timeline

philnik requested review of this revision.Dec 15 2021, 4:14 AM
philnik created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptDec 15 2021, 4:14 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
philnik retitled this revision from [libc++] Add GCC workaround for std::char_traits<char>::length() to [libc++] Add GCC workaround in std::char_traits<char>::length().Dec 15 2021, 4:16 AM
philnik edited the summary of this revision. (Show Details)
philnik edited the summary of this revision. (Show Details)
Quuxplusone requested changes to this revision.Dec 15 2021, 5:22 AM

The code itself looks reasonable, but I would expect to see some related changes in libcxx/test/.
Surely this allows us to eliminate one or more UNSUPPORTED: gcc-11 somewhere in the test suite.
Maybe even eliminate constexpr_char_traits.h altogether?! (But probably not.)

Also, looks like you're missing a level of indentation on lines 343–348.

This revision now requires changes to proceed.Dec 15 2021, 5:22 AM
Mordante added inline comments.
libcxx/include/__string
342

Please add a comment why this is needed and link to the GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816
This makes it easier to test later whether it's fixed by GCC.

philnik updated this revision to Diff 394606.Dec 15 2021, 10:52 AM
philnik marked an inline comment as done.
  • rebase
  • re-enable string.view.ops/copy.pass.cpp for gcc-11
  • Indent correctly
  • Add comment about GCC bug
philnik updated this revision to Diff 394634.Dec 15 2021, 12:07 PM
  • Added __ in front of i
Mordante accepted this revision as: Mordante.Dec 15 2021, 12:09 PM

LGTM after the build passes.

libcxx/include/__string
347
philnik updated this revision to Diff 394636.Dec 15 2021, 12:14 PM

Added char_type() around '\0'

philnik marked an inline comment as done.Dec 15 2021, 12:14 PM
ldionne accepted this revision.Dec 15 2021, 2:16 PM

Thanks!

Quuxplusone accepted this revision.Dec 15 2021, 2:39 PM

I'm still surprised that there's only one test affected by this; but my git grep-fu was unable to turn up any others.

Btw, this is a great illustration of the mantra "If you aren't testing it, it doesn't work". With your original PR, with zero libcxx/test/ diffs, you didn't find that single dumb typo. (Not a knock on your abilities — everyone makes such typos!) With one touch of libcxx/test/, ta-da, buildkite detected the typo for you. :) We should always make sure that when we change code, we're changing a codepath that is actually tested in the test suite — if it's not tested, dollars to donuts it doesn't work.

Ship it!

This revision is now accepted and ready to land.Dec 15 2021, 2:39 PM

With one touch of libcxx/test/, ta-da, buildkite detected the typo for you.

I'm not sure I understand this -- are you implying that BuildKite doesn't trigger tests if libcxx/test isn't touched? If so, that would be incorrect -- BuildKite triggers whenever anything at all under libcxx/ is touched, and all the tests are run regardless of what's actually been touched.

With one touch of libcxx/test/, ta-da, buildkite detected the typo for you.

I'm not sure I understand this -- are you implying that BuildKite doesn't trigger tests if libcxx/test isn't touched?

Not at all. "If it's not being tested, then it doesn't work" is an early-2000s-Green-Hills-Software mantra, but it's more or less the same idea as "If you liked it then you should have put a test on it." But a little less emphasis on interpersonal motivations and more just Murphy's Law: If some feature could be broken without making the build red, then I can pretty much guarantee you that it is broken right now.

Thus, whenever there's a code change, there had better be a test change too: Either we're fixing a previously-untested codepath (as in this case) so we should add a test, or we're fixing a previously-wrong codepath so we should modify a test. (Or it's completely NFC, which also wasn't the case here.) In the original submission, there was a code change but zero test changes; I said "Code LGTM but I'd expect to see a test change too" (because of everything I just said). And then @philnik added that test change, and lo and behold, that change immediately identified a typo-bug that had slipped past (I'm assuming) both of us!
If (hypothetically, and maybe you think this'd never happen ;)) we had all LGTM'ed the code and shipped it, it would have totally broken constexpr string_view on GCC. "Constexpr string_view on GCC" is the thing in this instance that we weren't testing (because it was XFAIL'ed), and therefore didn't work... and therefore, even after we thought "yeah, this should fix it," it actually continued not-to-work... until we put a test on it. :)

None of this has any particular ramifications for this PR at all. I'm just pointing at it and saying "Look, perfect minimal gem of an illustration as to why code changes should imply test changes!" This was like an 8-line diff, "obviously" correct. Staring at the code didn't find the typo (at least, not in my case). Mindless (at least, in my case ;)) application of the mantra led to its being found.

With one touch of libcxx/test/, ta-da, buildkite detected the typo for you.

I'm not sure I understand this -- are you implying that BuildKite doesn't trigger tests if libcxx/test isn't touched?

Not at all. "If it's not being tested, then it doesn't work" is an early-2000s-Green-Hills-Software mantra, but it's more or less the same idea as "If you liked it then you should have put a test on it." But a little less emphasis on interpersonal motivations and more just Murphy's Law: If some feature could be broken without making the build red, then I can pretty much guarantee you that it is broken right now.

Thus, whenever there's a code change, there had better be a test change too: Either we're fixing a previously-untested codepath (as in this case) so we should add a test, or we're fixing a previously-wrong codepath so we should modify a test. (Or it's completely NFC, which also wasn't the case here.) In the original submission, there was a code change but zero test changes; I said "Code LGTM but I'd expect to see a test change too" (because of everything I just said). And then @philnik added that test change, and lo and behold, that change immediately identified a typo-bug that had slipped past (I'm assuming) both of us!
If (hypothetically, and maybe you think this'd never happen ;)) we had all LGTM'ed the code and shipped it, it would have totally broken constexpr string_view on GCC. "Constexpr string_view on GCC" is the thing in this instance that we weren't testing (because it was XFAIL'ed), and therefore didn't work... and therefore, even after we thought "yeah, this should fix it," it actually continued not-to-work... until we put a test on it. :)

None of this has any particular ramifications for this PR at all. I'm just pointing at it and saying "Look, perfect minimal gem of an illustration as to why code changes should imply test changes!" This was like an 8-line diff, "obviously" correct. Staring at the code didn't find the typo (at least, not in my case). Mindless (at least, in my case ;)) application of the mantra led to its being found.

What I had misunderstood is that the test kept failing due to a typo and was hence "passing" the XFAIL test, but for a different reason. I understand and agree with everything you've said now that I understand that. Thanks for clarifying though.