This is an archive of the discontinued LLVM Phabricator instance.

[libc++][NFC] Mark LWG3573 as complete
ClosedPublic

Authored by jloser on Oct 15 2021, 8:31 PM.

Details

Summary

Mark LWG3573 as complete. It involves a change in wording around when
basic_string_view's constructor for iterator/sentinel can throw. The
current implementation is not marked conditionally noexcept, so there
is nothing to do here. Add a test that binds this behavior to verify the
constructor is not marked noexcept(true) when end - begin throws.

Diff Detail

Event Timeline

jloser requested review of this revision.Oct 15 2021, 8:31 PM
jloser created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptOct 15 2021, 8:31 PM
Herald added a reviewer: Restricted Project. · View Herald Transcript
Mordante requested changes to this revision.Oct 16 2021, 7:13 AM

Thanks for addressing these LWG-issues.

libcxx/test/std/strings/string.view/string.view.cons/from_iterator_sentinel.pass.cpp
54

It's possible to use Clang in a way it won't throw exceptions. This test fails in that context. Please guard all code you added with #ifndef TEST_HAS_NO_EXCEPTIONS.

55

Is there a reason for this return?

59

I'm not fond of constexpr since throwing isn't allowed in a constexpr function.

64

Please test the result of comparing the exception's what() against "LWG 3573".

This revision now requires changes to proceed.Oct 16 2021, 7:13 AM
Quuxplusone requested changes to this revision.Oct 16 2021, 7:42 AM
Quuxplusone added inline comments.
libcxx/test/std/strings/string.view/string.view.cons/from_iterator_sentinel.pass.cpp
54

You should know I'm going to object every time someone adds a global-namespace overloaded operator to a type that already defines its own operators. If throwing_sized_sentinel<I> IS-A sized_sentinel<I>, then its operator- shouldn't be doing anything different from the existing operator- of sized_sentinel<I>.
Also, although this is a technical nitpick, I believe throwing from operator- in this case violates the semantic requirement in https://eel.is/c++draft/iterator.concept.sizedsentinel#2.1 , which defines what operator- needs to return in this case (and implicitly defines that it does return).
Also, std::input_or_output_iterator auto should be I, and just generally this code is way more crufty than it could be.

I think we can get by with

template<class CharT>
struct ThrowingSentinel {
  friend bool operator==(const CharT*, ThrowingSentinel) noexcept;
  friend int operator-(const CharT *, ThrowingSentinel) noexcept;
  friend int operator-(ThrowingSentinel, const CharT *) { throw 42; }
};

template<class CharT>
void test_throwing() {
  auto val = MAKE_STRING_VIEW(CharT, "test");
  try {
    (void)std::basic_string_view<CharT>(val.begin(), ThrowingSentinel());
    assert(false);
  } catch (int i) {
    assert(i == 42);
  }
}
~~~
  test_throwing<char>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
  test_throwing<wchar_t>();
#endif
  test_throwing<char8_t>();
  test_throwing<char16_t>();
  test_throwing<char32_t>();

(I marked some undefined functions noexcept merely to try to be evil and trick the library into getting some intermediate noexcept-specification wrong. I don't really care about those noexcepts. Those functions are undefined because they will never be called.)

jloser updated this revision to Diff 380220.Oct 16 2021, 4:09 PM

Address Arthur's feedback

jloser updated this revision to Diff 380221.Oct 16 2021, 4:12 PM

Guard with TEST_HAS_NO_EXCEPTIONS

jloser marked 5 inline comments as done.Oct 16 2021, 4:19 PM

Thanks for addressing these LWG-issues.

libcxx/test/std/strings/string.view/string.view.cons/from_iterator_sentinel.pass.cpp
54

Good call, just guarded with TEST_HAS_NO_EXCEPTIONS.

54

Your suggestions are a good refactoring indeed -- just applied them. I did feel a bit bad writing that original operator- for throwing_sized_sentinel, but it did satisfy the requirements for the test. :)

As for the concept for sized_sentinel_for, it does indeed *need* to return std::iter_difference_t<I>. Note that your original writing with a return type of int would hard error in concept checking sized_sentinel_for for example. I'll wave my hands a bit on whether the return *is in fact reachable* (because in this case it's not due to the unconditional throwing, but it still "works").

55

It originally was strictly required to avoid hard erroring during concept checking sized_sentinel_for.

59

Removed.

jloser marked 4 inline comments as done.Oct 16 2021, 4:20 PM

Can you try to fix the CI? Also please verify the Cxx2bIssues.csv changes are still there. Maybe you need to rebase due to recent changes I did. Other then that it looks good.

jloser updated this revision to Diff 380391.Oct 18 2021, 7:32 AM

Add bodies to operator== and operator- for ThrowingSizedSentinel to avoid GCC warning about -Wnon-template-friend.

Can you try to fix the CI? Also please verify the Cxx2bIssues.csv changes are still there. Maybe you need to rebase due to recent changes I did. Other then that it looks good.

Just rebased and resolved the conflicts in Cxx2bIssues.csv. Also worked around the GCC warning causing CI to fail.

@Mordante @Quuxplusone this should be ready now!

ping @ldionne in case you're interested

ldionne accepted this revision.Oct 19 2021, 11:08 AM

Thanks!

This revision was not accepted when it landed; it landed in state Needs Review.Oct 19 2021, 11:19 AM
This revision was automatically updated to reflect the committed changes.