Skip to content

[libc++] Classify iota_view precondition #96662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 26, 2024

Conversation

ldionne
Copy link
Member

@ldionne ldionne commented Jun 25, 2024

Fixes #91385

@ldionne ldionne requested a review from a team as a code owner June 25, 2024 16:01
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jun 25, 2024
@llvmbot
Copy link
Member

llvmbot commented Jun 25, 2024

@llvm/pr-subscribers-libcxx

Author: Louis Dionne (ldionne)

Changes

Fixes #91385


Full diff: https://github.com/llvm/llvm-project/pull/96662.diff

2 Files Affected:

  • (modified) libcxx/include/__ranges/iota_view.h (+2-3)
  • (added) libcxx/test/std/ranges/range.factories/range.iota.view/assert.ctor.value.bound.pass.cpp (+26)
diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index 9e6f724241ccf..c0f5ed936a66d 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -22,7 +22,6 @@
 #include <__concepts/semiregular.h>
 #include <__concepts/totally_ordered.h>
 #include <__config>
-#include <__functional/ranges_operations.h>
 #include <__iterator/concepts.h>
 #include <__iterator/incrementable_traits.h>
 #include <__iterator/iterator_traits.h>
@@ -313,8 +312,8 @@ class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
       : __value_(std::move(__value)), __bound_sentinel_(std::move(__bound_sentinel)) {
     // Validate the precondition if possible.
     if constexpr (totally_ordered_with<_Start, _BoundSentinel>) {
-      _LIBCPP_ASSERT_UNCATEGORIZED(
-          ranges::less_equal()(__value_, __bound_sentinel_), "Precondition violated: value is greater than bound.");
+      _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+          bool(__value_ <= __bound_sentinel_), "iota_view: bound must be reachable from value");
     }
   }
 
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/assert.ctor.value.bound.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/assert.ctor.value.bound.pass.cpp
new file mode 100644
index 0000000000000..da21a32bf8298
--- /dev/null
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/assert.ctor.value.bound.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// Test the precondition check in iota_view(value, bound) that `bound` is reachable from `value`.
+
+#include <ranges>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  { TEST_LIBCPP_ASSERT_FAILURE(std::ranges::iota_view(5, 0), "iota_view: bound must be reachable from value"); }
+  { TEST_LIBCPP_ASSERT_FAILURE(std::ranges::iota_view(10, 5), "iota_view: bound must be reachable from value"); }
+
+  return 0;
+}

@frederick-vs-ja
Copy link
Contributor

frederick-vs-ja commented Jun 26, 2024

Any thoughts on this concern?

I was also wondering if instead of raising the error via a failure in the requires clause of the iota_view constructor guideline, it could be maybe raised earlier, e.g., from iota itself, with a nice message.

I've roughly tested the idea

  • extract a new _Integer_like_types_signedness_mismatch variable template,
  • use it in the constraints of the deduction guide, and then
  • copy the constraints of iota_view and its deduction guide to __iota::__fn::operator().

Error messages seem improved (Godbolt link).

@ldionne ldionne merged commit 637b7f8 into llvm:main Jun 26, 2024
54 of 57 checks passed
@ldionne ldionne deleted the review/iota-view-harden branch June 26, 2024 16:35
lravenclaw pushed a commit to lravenclaw/llvm-project that referenced this pull request Jul 3, 2024
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

libc++ iota constructor check hardened mode
3 participants