Skip to content

[libc++] implement std::flat_set #125241

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 24 commits into from
Mar 23, 2025
Merged

[libc++] implement std::flat_set #125241

merged 24 commits into from
Mar 23, 2025

Conversation

huixie90
Copy link
Member

No description provided.

Copy link

github-actions bot commented Jan 31, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the patch! I left some comments from our first pass at this.

@huixie90 huixie90 marked this pull request as ready for review February 9, 2025 09:28
@huixie90 huixie90 requested a review from a team as a code owner February 9, 2025 09:28
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Feb 9, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 9, 2025

@llvm/pr-subscribers-libcxx

Author: Hui (huixie90)

Changes

Patch is 336.17 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/125241.diff

91 Files Affected:

  • (modified) libcxx/docs/ReleaseNotes/21.rst (+1)
  • (modified) libcxx/docs/Status/Cxx23Papers.csv (+1-1)
  • (modified) libcxx/include/CMakeLists.txt (+2)
  • (added) libcxx/include/__flat_set/flat_set.h (+856)
  • (added) libcxx/include/flat_set (+59)
  • (modified) libcxx/include/module.modulemap (+16)
  • (modified) libcxx/modules/std.compat.cppm.in (-3)
  • (modified) libcxx/modules/std.cppm.in (+1-3)
  • (modified) libcxx/modules/std/flat_set.inc (+3-1)
  • (added) libcxx/test/libcxx/containers/container.adaptors/flat.set/assert.sorted_unique.pass.cpp (+226)
  • (modified) libcxx/test/libcxx/transitive_includes/cxx03.csv (+8)
  • (modified) libcxx/test/libcxx/transitive_includes/cxx11.csv (+8)
  • (modified) libcxx/test/libcxx/transitive_includes/cxx14.csv (+8)
  • (modified) libcxx/test/libcxx/transitive_includes/cxx17.csv (+8)
  • (modified) libcxx/test/libcxx/transitive_includes/cxx20.csv (+8)
  • (modified) libcxx/test/libcxx/transitive_includes/cxx23.csv (+14-1)
  • (modified) libcxx/test/libcxx/transitive_includes/cxx26.csv (+14)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/empty.pass.cpp (+52)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/empty.verify.cpp (+20)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/max_size.pass.cpp (+68)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/size.pass.cpp (+70)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/alloc.pass.cpp (+64)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/assign_initializer_list.pass.cpp (+61)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/compare.pass.cpp (+87)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/containers.pass.cpp (+157)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy.pass.cpp (+68)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy_alloc.pass.cpp (+67)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy_assign.pass.cpp (+100)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/deduct.compile.pass.cpp (+43)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/deduct.pass.cpp (+317)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/deduct_pmr.pass.cpp (+94)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/default.pass.cpp (+96)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/dtor_noexcept.pass.cpp (+61)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/initializer_list.pass.cpp (+155)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/iter_iter.pass.cpp (+140)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp (+188)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move_alloc.pass.cpp (+79)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move_assign.pass.cpp (+241)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/pmr.pass.cpp (+326)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/range.pass.cpp (+177)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_container.pass.cpp (+147)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_initializer_list.pass.cpp (+154)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_iter_iter.pass.cpp (+160)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.erasure/erase_if.pass.cpp (+93)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.erasure/erase_if_exceptions.pass.cpp (+133)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator.pass.cpp (+97)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator_comparison.pass.cpp (+158)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator_concept_conformance.compile.pass.cpp (+77)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/range_concept_conformance.compile.pass.cpp (+52)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/reverse_iterator.pass.cpp (+91)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/clear.pass.cpp (+66)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/emplace.pass.cpp (+146)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/emplace_hint.pass.cpp (+159)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/erase_iter.pass.cpp (+126)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/erase_iter_iter.pass.cpp (+97)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/erase_key.pass.cpp (+96)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/erase_key_transparent.pass.cpp (+148)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/extract.pass.cpp (+92)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_cv.pass.cpp (+83)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_initializer_list.pass.cpp (+73)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_iter_cv.pass.cpp (+80)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_iter_iter.pass.cpp (+94)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_iter_rv.pass.cpp (+78)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_range.pass.cpp (+103)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_rv.pass.cpp (+86)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_sorted_initializer_list.pass.cpp (+63)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_sorted_iter_iter.pass.cpp (+82)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_transparent.pass.cpp (+178)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/replace.pass.cpp (+78)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp (+61)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_free.pass.cpp (+100)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_member.pass.cpp (+96)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.observers/comp.pass.cpp (+76)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/contains.pass.cpp (+73)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/contains_transparent.pass.cpp (+75)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/count.pass.cpp (+73)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/count_transparent.pass.cpp (+75)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/equal_range.pass.cpp (+81)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/equal_range_transparent.pass.cpp (+101)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/find.pass.cpp (+57)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/find_transparent.pass.cpp (+92)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/lower_bound.pass.cpp (+74)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/lower_bound_transparent.pass.cpp (+98)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/upper_bound.pass.cpp (+75)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/upper_bound_transparent.pass.cpp (+98)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/helpers.h (+307)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/incomplete_type.pass.cpp (+36)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/op_compare.pass.cpp (+110)
  • (added) libcxx/test/std/containers/container.adaptors/flat.set/types.compile.pass.cpp (+94)
  • (added) libcxx/test/std/language.support/support.limits/support.limits.general/flat_set.version.compile.pass.cpp (+80)
  • (modified) libcxx/utils/libcxx/header_information.py (+1-1)
diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst
index 82f1de6bad39423..0c1029f50a6fe7d 100644
--- a/libcxx/docs/ReleaseNotes/21.rst
+++ b/libcxx/docs/ReleaseNotes/21.rst
@@ -39,6 +39,7 @@ Implemented Papers
 ------------------
 
 - N4258: Cleaning-up noexcept in the Library (`Github <https://github.com/llvm/llvm-project/issues/99937>`__)
+- P1222R4: A Standard ``flat_set`` is partially implemented and ``flat_set`` is provided (`Github <https://github.com/llvm/llvm-project/issues/105193>`__)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index 264c5417a5c28be..bcd9c5c43a9c695 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -54,7 +54,7 @@
 "`P0009R18 <https://wg21.link/P0009R18>`__","mdspan: A Non-Owning Multidimensional Array Reference","2022-07 (Virtual)","|Complete|","18",""
 "`P0429R9 <https://wg21.link/P0429R9>`__","A Standard ``flat_map``","2022-07 (Virtual)","|Complete|","20",""
 "`P1169R4 <https://wg21.link/P1169R4>`__","``static operator()``","2022-07 (Virtual)","|Complete|","16",""
-"`P1222R4 <https://wg21.link/P1222R4>`__","A Standard ``flat_set``","2022-07 (Virtual)","","",""
+"`P1222R4 <https://wg21.link/P1222R4>`__","A Standard ``flat_set``","2022-07 (Virtual)","|In progress|","",""
 "`P1223R5 <https://wg21.link/P1223R5>`__","``ranges::find_last()``, ``ranges::find_last_if()``, and ``ranges::find_last_if_not()``","2022-07 (Virtual)","|Complete|","19",""
 "`P1467R9 <https://wg21.link/P1467R9>`__","Extended ``floating-point`` types and standard names","2022-07 (Virtual)","","",""
 "`P1642R11 <https://wg21.link/P1642R11>`__","Freestanding ``[utilities]``, ``[ranges]``, and ``[iterators]``","2022-07 (Virtual)","","",""
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 8dac823503d73f5..75acf9f7899ff66 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -367,6 +367,7 @@ set(files
   __flat_map/sorted_equivalent.h
   __flat_map/sorted_unique.h
   __flat_map/utils.h
+  __flat_set/flat_set.h
   __format/buffer.h
   __format/concepts.h
   __format/container_adaptor.h
@@ -986,6 +987,7 @@ set(files
   fenv.h
   filesystem
   flat_map
+  flat_set
   float.h
   format
   forward_list
diff --git a/libcxx/include/__flat_set/flat_set.h b/libcxx/include/__flat_set/flat_set.h
new file mode 100644
index 000000000000000..30fe1343e63ee9d
--- /dev/null
+++ b/libcxx/include/__flat_set/flat_set.h
@@ -0,0 +1,856 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FLAT_SET_FLAT_SET_H
+#define _LIBCPP___FLAT_SET_FLAT_SET_H
+
+#include <__algorithm/lexicographical_compare_three_way.h>
+#include <__algorithm/min.h>
+#include <__algorithm/ranges_adjacent_find.h>
+#include <__algorithm/ranges_equal.h>
+#include <__algorithm/ranges_inplace_merge.h>
+#include <__algorithm/ranges_lower_bound.h>
+#include <__algorithm/ranges_partition_point.h>
+#include <__algorithm/ranges_sort.h>
+#include <__algorithm/ranges_unique.h>
+#include <__algorithm/ranges_upper_bound.h>
+#include <__algorithm/remove_if.h>
+#include <__assert>
+#include <__compare/synth_three_way.h>
+#include <__concepts/swappable.h>
+#include <__config>
+#include <__cstddef/byte.h>
+#include <__cstddef/ptrdiff_t.h>
+#include <__flat_map/sorted_unique.h>
+#include <__functional/invoke.h>
+#include <__functional/is_transparent.h>
+#include <__functional/operations.h>
+#include <__fwd/vector.h>
+#include <__iterator/concepts.h>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/ranges_iterator_traits.h>
+#include <__iterator/reverse_iterator.h>
+#include <__memory/allocator_traits.h>
+#include <__memory/uses_allocator.h>
+#include <__memory/uses_allocator_construction.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/drop_view.h>
+#include <__ranges/from_range.h>
+#include <__ranges/ref_view.h>
+#include <__ranges/size.h>
+#include <__ranges/subrange.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/container_traits.h>
+#include <__type_traits/invoke.h>
+#include <__type_traits/is_allocator.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_same.h>
+#include <__utility/exception_guard.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
+#include <__utility/scope_guard.h>
+#include <__vector/vector.h>
+#include <initializer_list>
+#include <stdexcept>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Key, class _Compare = less<_Key>, class _KeyContainer = vector<_Key>>
+class flat_set {
+  template <class, class, class>
+  friend class flat_set;
+
+  static_assert(is_same_v<_Key, typename _KeyContainer::value_type>);
+  static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
+
+public:
+  // types
+  using key_type               = _Key;
+  using value_type             = _Key;
+  using key_compare            = __type_identity_t<_Compare>;
+  using value_compare          = _Compare;
+  using reference              = value_type&;
+  using const_reference        = const value_type&;
+  using size_type              = typename _KeyContainer::size_type;
+  using difference_type        = typename _KeyContainer::difference_type;
+  using iterator               = typename _KeyContainer::const_iterator;
+  using const_iterator         = iterator;
+  using reverse_iterator       = std::reverse_iterator<iterator>;
+  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+  using container_type         = _KeyContainer;
+
+public:
+  // [flat.set.cons], construct/copy/destroy
+  _LIBCPP_HIDE_FROM_ABI
+  flat_set() noexcept(is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_Compare>)
+      : __keys_(), __compare_() {}
+
+  _LIBCPP_HIDE_FROM_ABI flat_set(const flat_set&) = default;
+
+  _LIBCPP_HIDE_FROM_ABI flat_set(flat_set&& __other) noexcept(
+      is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_Compare>)
+#  if _LIBCPP_HAS_EXCEPTIONS
+      try
+#  endif // _LIBCPP_HAS_EXCEPTIONS
+      : __keys_(std::move(__other.__keys_)), __compare_(std::move(__other.__compare_)) {
+    __other.clear();
+#  if _LIBCPP_HAS_EXCEPTIONS
+  } catch (...) {
+    __other.clear();
+    // gcc does not like the `throw` keyword in a conditionally noexcept function
+    if constexpr (!(is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_Compare>)) {
+      throw;
+    }
+#  endif // _LIBCPP_HAS_EXCEPTIONS
+  }
+
+  _LIBCPP_HIDE_FROM_ABI explicit flat_set(const key_compare& __comp) : __keys_(), __compare_(__comp) {}
+
+  _LIBCPP_HIDE_FROM_ABI explicit flat_set(container_type __keys, const key_compare& __comp = key_compare())
+      : __keys_(std::move(__keys)), __compare_(__comp) {
+    __sort_and_unique();
+  }
+
+  _LIBCPP_HIDE_FROM_ABI flat_set(sorted_unique_t, container_type __keys, const key_compare& __comp = key_compare())
+      : __keys_(std::move(__keys)), __compare_(__comp) {
+    _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
+        __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates");
+  }
+
+  template <class _InputIterator>
+    requires __has_input_iterator_category<_InputIterator>::value
+  _LIBCPP_HIDE_FROM_ABI
+  flat_set(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare())
+      : __keys_(), __compare_(__comp) {
+    insert(__first, __last);
+  }
+
+  template <class _InputIterator>
+    requires __has_input_iterator_category<_InputIterator>::value
+  _LIBCPP_HIDE_FROM_ABI
+  flat_set(sorted_unique_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare())
+      : __keys_(__first, __last), __compare_(__comp) {
+    _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
+        __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates");
+  }
+
+  template <_ContainerCompatibleRange<value_type> _Range>
+  _LIBCPP_HIDE_FROM_ABI flat_set(from_range_t, _Range&& __rg)
+      : flat_set(from_range, std::forward<_Range>(__rg), key_compare()) {}
+
+  template <_ContainerCompatibleRange<value_type> _Range>
+  _LIBCPP_HIDE_FROM_ABI flat_set(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_set(__comp) {
+    insert_range(std::forward<_Range>(__rg));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI flat_set(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
+      : flat_set(__il.begin(), __il.end(), __comp) {}
+
+  _LIBCPP_HIDE_FROM_ABI
+  flat_set(sorted_unique_t, initializer_list<value_type> __il, const key_compare& __comp = key_compare())
+      : flat_set(sorted_unique, __il.begin(), __il.end(), __comp) {}
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI explicit flat_set(const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_empty_tag{}, __alloc) {}
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI flat_set(const key_compare& __comp, const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {}
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI flat_set(const container_type& __keys, const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_tag{}, __alloc, __keys) {
+    __sort_and_unique();
+  }
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI flat_set(const container_type& __keys, const key_compare& __comp, const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_tag{}, __alloc, __keys, __comp) {
+    __sort_and_unique();
+  }
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI flat_set(sorted_unique_t, const container_type& __keys, const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_tag{}, __alloc, __keys) {
+    _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
+        __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates");
+  }
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI
+  flat_set(sorted_unique_t, const container_type& __keys, const key_compare& __comp, const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_tag{}, __alloc, __keys, __comp) {
+    _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
+        __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates");
+  }
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI flat_set(const flat_set& __other, const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_tag{}, __alloc, __other.__keys_, __other.__compare_) {}
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI flat_set(flat_set&& __other, const _Allocator& __alloc)
+#  if _LIBCPP_HAS_EXCEPTIONS
+      try
+#  endif // _LIBCPP_HAS_EXCEPTIONS
+      : flat_set(__ctor_uses_allocator_tag{}, __alloc, std::move(__other.__keys_), std::move(__other.__compare_)) {
+    __other.clear();
+#  if _LIBCPP_HAS_EXCEPTIONS
+  } catch (...) {
+    __other.clear();
+    throw;
+#  endif // _LIBCPP_HAS_EXCEPTIONS
+  }
+
+  template <class _InputIterator, class _Allocator>
+    requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
+  _LIBCPP_HIDE_FROM_ABI flat_set(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_empty_tag{}, __alloc) {
+    insert(__first, __last);
+  }
+
+  template <class _InputIterator, class _Allocator>
+    requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
+  _LIBCPP_HIDE_FROM_ABI
+  flat_set(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {
+    insert(__first, __last);
+  }
+
+  template <class _InputIterator, class _Allocator>
+    requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
+  _LIBCPP_HIDE_FROM_ABI
+  flat_set(sorted_unique_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_empty_tag{}, __alloc) {
+    insert(sorted_unique, __first, __last);
+  }
+
+  template <class _InputIterator, class _Allocator>
+    requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
+  _LIBCPP_HIDE_FROM_ABI
+  flat_set(sorted_unique_t,
+           _InputIterator __first,
+           _InputIterator __last,
+           const key_compare& __comp,
+           const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {
+    insert(sorted_unique, __first, __last);
+  }
+
+  template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI flat_set(from_range_t, _Range&& __rg, const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_empty_tag{}, __alloc) {
+    insert_range(std::forward<_Range>(__rg));
+  }
+
+  template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI flat_set(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc)
+      : flat_set(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {
+    insert_range(std::forward<_Range>(__rg));
+  }
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI flat_set(initializer_list<value_type> __il, const _Allocator& __alloc)
+      : flat_set(__il.begin(), __il.end(), __alloc) {}
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI
+  flat_set(initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc)
+      : flat_set(__il.begin(), __il.end(), __comp, __alloc) {}
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI flat_set(sorted_unique_t, initializer_list<value_type> __il, const _Allocator& __alloc)
+      : flat_set(sorted_unique, __il.begin(), __il.end(), __alloc) {}
+
+  template <class _Allocator>
+    requires uses_allocator<container_type, _Allocator>::value
+  _LIBCPP_HIDE_FROM_ABI
+  flat_set(sorted_unique_t, initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc)
+      : flat_set(sorted_unique, __il.begin(), __il.end(), __comp, __alloc) {}
+
+  _LIBCPP_HIDE_FROM_ABI flat_set& operator=(initializer_list<value_type> __il) {
+    clear();
+    insert(__il);
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI flat_set& operator=(const flat_set&) = default;
+
+  _LIBCPP_HIDE_FROM_ABI flat_set& operator=(flat_set&& __other) noexcept(
+      is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_Compare>) {
+    // No matter what happens, we always want to clear the other container before returning
+    // since we moved from it
+    auto __clear_other_guard = std::__make_scope_guard([&]() noexcept { __other.clear() /* noexcept */; });
+    {
+      // If an exception is thrown, we have no choice but to clear *this to preserve invariants
+      auto __on_exception = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
+      __keys_             = std::move(__other.__keys_);
+      __compare_          = std::move(__other.__compare_);
+      __on_exception.__complete();
+    }
+    return *this;
+  }
+
+  // iterators
+  _LIBCPP_HIDE_FROM_ABI iterator begin() noexcept { return __keys_.begin(); }
+  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { return __keys_.begin(); }
+  _LIBCPP_HIDE_FROM_ABI iterator end() noexcept { return __keys_.end(); }
+  _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { return __keys_.end(); }
+
+  _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
+  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
+  _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
+  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
+
+  _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return begin(); }
+  _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return end(); }
+  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
+  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
+
+  // [flat.set.capacity], capacity
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __keys_.empty(); }
+
+  _LIBCPP_HIDE_FROM_ABI size_type size() const noexcept { return __keys_.size(); }
+
+  _LIBCPP_HIDE_FROM_ABI size_type max_size() const noexcept { return __keys_.max_size(); }
+
+  // [flat.set.modifiers], modifiers
+  template <class... _Args>
+  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> emplace(_Args&&... __args) {
+    if constexpr (sizeof...(__args) == 1 && (is_same_v<remove_cvref_t<_Args>, _Key> && ...)) {
+      return __try_emplace(std::forward<_Args>(__args)...);
+    } else {
+      return __try_emplace(_Key(std::forward<_Args>(__args)...));
+    }
+  }
+
+  template <class... _Args>
+  _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __hint, _Args&&... __args) {
+    if constexpr (sizeof...(__args) == 1 && (is_same_v<remove_cvref_t<_Args>, _Key> && ...)) {
+      return __emplace_hint(std::move(__hint), std::forward<_Args>(__args)...);
+    } else {
+      return __emplace_hint(std::move(__hint), _Key(std::forward<_Args>(__args)...));
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __x) { return emplace(__x); }
+
+  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(value_type&& __x) { return emplace(std::move(__x)); }
+
+  template <class _Kp>
+    requires(__is_transparent_v<_Compare> && is_constructible_v<value_type, _Kp>)
+  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(_Kp&& __x) {
+    return emplace(std::forward<_Kp>(__x));
+  }
+  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, const value_type& __x) {
+    return emplace_hint(__hint, __x);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, value_type&& __x) {
+    return emplace_hint(__hint, std::move(__x));
+  }
+
+  template <class _Kp>
+    requires(__is_transparent_v<_Compare> && is_constructible_v<value_type, _Kp>)
+  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, _Kp&& __x) {
+    return emplace_hint(__hint, std::forward<_Kp>(__x));
+  }
+
+  template <class _InputIterator>
+    requires __has_input_iterator_category<_InputIterator>::value
+  _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) {
+    if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) {
+      __reserve(__last - __first);
+    }
+    __append_so...
[truncated]

// for feature-test macros
# include <version>

// standard required includes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about implementing LWG3987 (#105309)? Is it already implemented by the complicated transitive inclusions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this touches flat_map as well. I'd like to do it in a separate patch and make this patch flat_set only

@huixie90 huixie90 force-pushed the hxie/flat_set branch 3 times, most recently from fb94ba2 to 5f12c9c Compare March 9, 2025 18:40
Comment on lines +122 to +127
_LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __ra_iterator& __x, const __ra_iterator& __y)
requires three_way_comparable<_Iterator>
{
return __x.__iter_ <=> __y.__iter_;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC the requires here is unnecessary. As specified in [container.reqmts]/39, /40, and /41, use of non-three-way-comparable iterator here is invalid, and the return type is required to be std::strong_ordering.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As Hui was explaining to me just now, these requirements are added by containers. But if we want to reuse this iterator type in other contexts, these requirements might not apply and so we are probably better off with the more general implementation.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with very minor nits, and CI passing. Thanks a lot for the patch and the very thorough testing, this is great!

@ldionne ldionne added the pending-ci Merging the PR is only pending completion of CI label Mar 21, 2025
@huixie90 huixie90 merged commit 2f1416b into llvm:main Mar 23, 2025
82 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 23, 2025

LLVM Buildbot has detected a new failure on builder sanitizer-x86_64-linux-fast running on sanitizer-buildbot3 while building libcxx at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/169/builds/9727

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using lld-link: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/lld-link
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld64.lld: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using wasm-ld: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld.lld: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/ld.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using lld-link: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/lld-link
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld64.lld: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using wasm-ld: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/main.py:72: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 89739 tests, 88 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 
FAIL: Clang :: Interpreter/inline-virtual.cpp (17182 of 89739)
******************** TEST 'Clang :: Interpreter/inline-virtual.cpp' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 6: cat /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp | /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/clang-repl -Xcc -fno-rtti -Xcc -fno-sized-deallocation      | /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
+ /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/clang-repl -Xcc -fno-rtti -Xcc -fno-sized-deallocation
+ /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
+ cat /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
RUN: at line 8: cat /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp | /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/clang-repl -Xcc -fno-rtti -Xcc -fno-sized-deallocation      -Xcc -O2 | /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
+ /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/clang-repl -Xcc -fno-rtti -Xcc -fno-sized-deallocation -Xcc -O2
+ cat /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
+ /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
JIT session error: In graph incr_module_23-jitted-objectbuffer, section .text.startup: relocation target "_ZTV1A" at address 0x776ffd22e000 is out of range of Delta32 fixup at 0x736ffc90f013 (<anonymous block> @ 0x736ffc90f010 + 0x3)
error: Failed to materialize symbols: { (main, { $.incr_module_23.__inits.0, __orc_init_func.incr_module_23, a2 }) }
error: Failed to materialize symbols: { (main, { __orc_init_func.incr_module_23 }) }
/home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp:26:11: error: CHECK: expected string not found in input
// CHECK: ~A(2)
          ^
<stdin>:1:262: note: scanning from here
clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl... clang-repl> clang-repl... clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> ~A(1)
                                                                                                                                                                                                                                                                     ^

Input file: <stdin>
Check file: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
          1: clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl... clang-repl> clang-repl... clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> ~A(1) 
check:26                                                                                                                                                                                                                                                                          X error: no match found
          2: clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl>  
check:26     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>>

--

Step 10 (stage2/asan_ubsan check) failure: stage2/asan_ubsan check (failure)
...
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using lld-link: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/lld-link
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld64.lld: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using wasm-ld: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld.lld: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/ld.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using lld-link: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/lld-link
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld64.lld: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using wasm-ld: /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/utils/lit/lit/main.py:72: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 89739 tests, 88 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 
FAIL: Clang :: Interpreter/inline-virtual.cpp (17182 of 89739)
******************** TEST 'Clang :: Interpreter/inline-virtual.cpp' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 6: cat /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp | /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/clang-repl -Xcc -fno-rtti -Xcc -fno-sized-deallocation      | /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
+ /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/clang-repl -Xcc -fno-rtti -Xcc -fno-sized-deallocation
+ /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
+ cat /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
RUN: at line 8: cat /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp | /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/clang-repl -Xcc -fno-rtti -Xcc -fno-sized-deallocation      -Xcc -O2 | /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
+ /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/clang-repl -Xcc -fno-rtti -Xcc -fno-sized-deallocation -Xcc -O2
+ cat /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
+ /home/b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
JIT session error: In graph incr_module_23-jitted-objectbuffer, section .text.startup: relocation target "_ZTV1A" at address 0x776ffd22e000 is out of range of Delta32 fixup at 0x736ffc90f013 (<anonymous block> @ 0x736ffc90f010 + 0x3)
error: Failed to materialize symbols: { (main, { $.incr_module_23.__inits.0, __orc_init_func.incr_module_23, a2 }) }
error: Failed to materialize symbols: { (main, { __orc_init_func.incr_module_23 }) }
/home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp:26:11: error: CHECK: expected string not found in input
// CHECK: ~A(2)
          ^
<stdin>:1:262: note: scanning from here
clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl... clang-repl> clang-repl... clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> ~A(1)
                                                                                                                                                                                                                                                                     ^

Input file: <stdin>
Check file: /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
          1: clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl... clang-repl> clang-repl... clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> ~A(1) 
check:26                                                                                                                                                                                                                                                                          X error: no match found
          2: clang-repl> clang-repl> clang-repl> clang-repl> clang-repl> clang-repl>  
check:26     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>>

--


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. pending-ci Merging the PR is only pending completion of CI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants