This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Fix std::__debug_less in c++17.
ClosedPublic

Authored by rupprecht on Feb 3 2022, 12:40 PM.

Details

Summary

b07b5bd72716625e0976a84d23652d94d8d0165a adds a use of __comp_ref_type.h to std::min. When libc++ is built with -D_LIBCPP_DEBUG=0, this enables std::__debug_less, which is only marked constexpr after c++17.

std::min itself is marked as being constexpr as of c++14, so by extension, std::__debug_less should also be marked constexpr for the same versions so that std::min can use it. This change lowers the guard from > 17 to > 11.

Reproducer in godbolt: https://godbolt.org/z/ans3TGsj8

constexpr int x() { return std::min<int>({1, 2, 3, 4}); }

static_assert(x() == 1);

Diff Detail

Event Timeline

rupprecht requested review of this revision.Feb 3 2022, 12:40 PM
rupprecht created this revision.
Herald added a project: Restricted Project. · View Herald Transcript
Herald added a reviewer: Restricted Project. · View Herald Transcript
philnik accepted this revision as: philnik.Feb 3 2022, 12:51 PM
philnik added a subscriber: philnik.

LGTM % nits.

libcxx/include/__algorithm/comp_ref_type.h
25

Pre-existing: This should be _LIBCPP_DEBUG_LEVEL == 1.

56

Please replace _LIBCPP_INLINE_VISIBILITY with _LIBCPP_HIDE_FROM_ABI as a fly-by.

libcxx/test/libcxx/algorithms/debug_less.pass.cpp
276
rupprecht updated this revision to Diff 405770.Feb 3 2022, 1:38 PM
rupprecht marked 3 inline comments as done.
  • Use _LIBCPP_HIDE_FROM_ABI
  • Use `_LIBCPP_DEBUG_LEVEL
  • Fix clang-format CI test failure
  • Fix whitespace in test
rupprecht added inline comments.Feb 3 2022, 1:40 PM
libcxx/include/__algorithm/comp_ref_type.h
25

IIUC, _LIBCPP_DEBUG_LEVEL=2 should provide a superset of _LIBCPP_DEBUG_LEVEL=1: https://github.com/llvm/llvm-project/blob/c3c1c5c6953fcf9320a0cae5121ce55839169790/libcxx/include/__config#L907

Did you want #if _LIBCPP_DEBUG_LEVEL >= 1?

61

FYI, this change doesn't look very pleasant, but the clang-format test on libcxx CI was failing, and clang-format does this.

philnik added inline comments.Feb 3 2022, 1:52 PM
libcxx/include/__algorithm/comp_ref_type.h
25

Oh sorry, that is what I meant.

61

The clang-format check isn't a hard error, you can (and should) revert that part.

As philnik said, please revert all the extraneous changes. (And please ignore clang-format's noise going forward. We'd disable clang-format entirely if we could. This is an ongoing pain point for libc++, over and over and over.)

IIUC, the only intentional functional change here is to change _LIBCPP_CONSTEXPR_AFTER_CXX17 into _LIBCPP_CONSTEXPR_AFTER_CXX11, is that right? That certainly seems like a good idea to me. (My mantra there is that internal details should always use the most aggressive constexpr possible. That way, if we ever drop support for C++03 and C++11 modes, the amount of stuff can be search-and-replaced to plain constexpr immediately is maximized.)

Contrariwise, your changes to _LIBCPP_DEBUG seem extraneous and/or wrong; I don't think you should touch anything in this PR that isn't related to the bug you're trying to fix. (And if we were going to touch anything in that area, I'd suggest that we remove the #ifs around __debug_less: I see no reason ever to if-out its class definition, even if it's sometimes unused.)

libcxx/include/__algorithm/comp_ref_type.h
76

This is definitely wrong, because _LIBCPP_DEBUG might not be defined at all, in which case this change will trigger -Wundef. Please leave _LIBCPP_DEBUG alone unless it's related to your patch.

rupprecht updated this revision to Diff 405791.Feb 3 2022, 2:23 PM
  • Undo clang-formatting
rupprecht updated this revision to Diff 405794.Feb 3 2022, 2:26 PM
  • Restoring original version of the patch

As philnik said, please revert all the extraneous changes. (And please ignore clang-format's noise going forward. We'd disable clang-format entirely if we could. This is an ongoing pain point for libc++, over and over and over.)

IIUC, the only intentional functional change here is to change _LIBCPP_CONSTEXPR_AFTER_CXX17 into _LIBCPP_CONSTEXPR_AFTER_CXX11, is that right? That certainly seems like a good idea to me. (My mantra there is that internal details should always use the most aggressive constexpr possible. That way, if we ever drop support for C++03 and C++11 modes, the amount of stuff can be search-and-replaced to plain constexpr immediately is maximized.)

Contrariwise, your changes to _LIBCPP_DEBUG seem extraneous and/or wrong; I don't think you should touch anything in this PR that isn't related to the bug you're trying to fix. (And if we were going to touch anything in that area, I'd suggest that we remove the #ifs around __debug_less: I see no reason ever to if-out its class definition, even if it's sometimes unused.)

I don't particularly care if we remove the _LIBCPP_DEBUGs around __debug_less, but I think they can stay in.

libcxx/include/__algorithm/comp_ref_type.h
76

If _LIBCPP_DEBUG isn't defined, _LIBCPP_DEBUG_LEVEL is 0. This should probabl just be == 0, but it's not wrong.

As philnik said, please revert all the extraneous changes. (And please ignore clang-format's noise going forward. We'd disable clang-format entirely if we could. This is an ongoing pain point for libc++, over and over and over.)

IIUC, the only intentional functional change here is to change _LIBCPP_CONSTEXPR_AFTER_CXX17 into _LIBCPP_CONSTEXPR_AFTER_CXX11, is that right? That certainly seems like a good idea to me. (My mantra there is that internal details should always use the most aggressive constexpr possible. That way, if we ever drop support for C++03 and C++11 modes, the amount of stuff can be search-and-replaced to plain constexpr immediately is maximized.)

That's correct -- supporting this for C++17 was the only change I care about.

Contrariwise, your changes to _LIBCPP_DEBUG seem extraneous and/or wrong; I don't think you should touch anything in this PR that isn't related to the bug you're trying to fix. (And if we were going to touch anything in that area, I'd suggest that we remove the #ifs around __debug_less: I see no reason ever to if-out its class definition, even if it's sometimes unused.)

I lean towards not making unrelated changes in patches, but I wasn't sure how libc++ reviewers felt about this, so I made those changes after review comments. They're reverted now. How about I land just the part I care about in this commit, and do the rest in a followup?

  • Replacing uses of _LIBCPP_DEBUG with checking _LIBCPP_DEBUG_LEVEL levels instead seems limited to just this file
  • Replacing uses of _LIBCPP_INLINE_VISIBILITY with _LIBCPP_HIDE_FROM_ABI seems a lot larger (289 files affected, if I'm grepping correctly), so I'd prefer not to do the whole cleanup (although it's not complex -- it's just a sed command), but I could do it for this file.
libcxx/include/__algorithm/comp_ref_type.h
76

The patch looks good to me now... but we do have a buildkite runner that runs in Debug mode, and it didn't catch the thing you originally mentioned.
Can someone explain why libcxx/test/std/algorithms/alg.sorting/alg.min.max/min_init_list_comp.pass.cpp does not detect the problem? I paste it into Godbolt and it detects the problem: https://godbolt.org/z/eKvcvbb7d yet the "Debug mode" buildkite job isn't failing.

...Ooh. It's because the "Debug mode" buildkite job uses only C++20 or C++2b, isn't it? The combinatorial explosion of config options strikes again. :( @ldionne @philnik any thoughts on how to improve our CI coverage here?

The patch looks good to me now... but we do have a buildkite runner that runs in Debug mode, and it didn't catch the thing you originally mentioned.
Can someone explain why libcxx/test/std/algorithms/alg.sorting/alg.min.max/min_init_list_comp.pass.cpp does not detect the problem? I paste it into Godbolt and it detects the problem: https://godbolt.org/z/eKvcvbb7d yet the "Debug mode" buildkite job isn't failing.

...Ooh. It's because the "Debug mode" buildkite job uses only C++20 or C++2b, isn't it? The combinatorial explosion of config options strikes again. :( @ldionne @philnik any thoughts on how to improve our CI coverage here?

Yeah, exponential growth really sucks. A few things I thought of:
(1) Have an infinite amount of money to throw at CI. That would mean we have 0 bugs, but it might not be feasible.
(2) Ignore it and hope for the best
(3) It would still be expensive, but we could see how expensive it is to only compile all the tests, and therefore effectively only testing constexpr with debug
(4) Remove some configurations

I guess option 3 would be the best option, but it might be too costly. So it's most likely going to be option 2.

The patch looks good to me now... but we do have a buildkite runner that runs in Debug mode, and it didn't catch the thing you originally mentioned.
Can someone explain why libcxx/test/std/algorithms/alg.sorting/alg.min.max/min_init_list_comp.pass.cpp does not detect the problem? I paste it into Godbolt and it detects the problem: https://godbolt.org/z/eKvcvbb7d yet the "Debug mode" buildkite job isn't failing.

...Ooh. It's because the "Debug mode" buildkite job uses only C++20 or C++2b, isn't it? The combinatorial explosion of config options strikes again. :( @ldionne @philnik any thoughts on how to improve our CI coverage here?

Yeah, exponential growth really sucks. A few things I thought of:
(1) Have an infinite amount of money to throw at CI. That would mean we have 0 bugs, but it might not be feasible.
(2) Ignore it and hope for the best

Also seems the most reasonable IMHO. Breakages seem pretty rare, I don't know if it's worth a bunch of resources for a once-a-year bug.

(3) It would still be expensive, but we could see how expensive it is to only compile all the tests, and therefore effectively only testing constexpr with debug
(4) Remove some configurations

I guess option 3 would be the best option, but it might be too costly. So it's most likely going to be option 2.

This revision is now accepted and ready to land.Feb 4 2022, 9:34 AM
ldionne accepted this revision.Feb 4 2022, 1:12 PM

LGTM, and I agree that it's probably not worth the cost to solve this specific issue in CI.

This revision was automatically updated to reflect the committed changes.