Hi Sylvestre, Unfortunately, I did NOT get your reply from the Debian-BR-system.
Furthermore, I have no user (guest) account on <salsa.debian.org>, so a MR (Merge-Request) seems not possible for me. So, I cloned the latest debian "llvm-toolchain-14" from salsa-Git. git clone https://salsa.debian.org/pkg-llvm-team/llvm-toolchain.git debian cd debian/ git checkout origin/14 -b llvm-toolchain-14 [ EDIT debian/patches/series ] git add debian/patches/series debian/patches/0001-libc-Add-workaround-to-avoid-breaking-users-of-span-.patch debian/patches/0002-libc-Re-enable-workaround-for-pre-ranges-CTAD-in-std.patch git commit -m 'Add libc++ patches from upstream (post version 14.0.0)' git format-patch --signoff -1 That patch is attached here. I have not modified debian/changelog and it does not look like it is the latest: $ head -10 debian/changelog llvm-toolchain-14 (1:14.0.0~+rc4-1) unstable; urgency=medium * New snapshot release (rc3 isn't a thing) * Add an ugly workaround for Ubuntu jammy (some python files are installed in local/lib) -- Sylvestre Ledru <sylves...@debian.org> Fri, 11 Mar 2022 18:28:07 +0100 llvm-toolchain-14 (1:14.0.0~+rc2-1~exp1) unstable; urgency=medium * New snapshot release I have not tried or checked if my patch is applied when using the latest orig-tarball and latest debian-tarball. Normally, I would use dsc | orig-tarball | debian-tarball from [2], [3] and [4]. Is that attached patch helpful for you or not? Thanks. Regards, - Sedat - [1] https://packages.debian.org/sid/clang-14 [2] http://deb.debian.org/debian/pool/main/l/llvm-toolchain-14/llvm-toolchain-14_14.0.0-1.dsc [3] http://deb.debian.org/debian/pool/main/l/llvm-toolchain-14/llvm-toolchain-14_14.0.0.orig.tar.xz [4] http://deb.debian.org/debian/pool/main/l/llvm-toolchain-14/llvm-toolchain-14_14.0.0-1.debian.tar.xz
From 3f786648773a5ce334604d7a400505fc97196226 Mon Sep 17 00:00:00 2001 From: Sedat Dilek <sedat.di...@gmail.com> Date: Wed, 30 Mar 2022 18:03:22 +0200 Subject: [PATCH] Add libc++ patches from upstream (post version 14.0.0) Details see Debian bug #1008657 ("clang-14: Integrate post v14.0.0 upstream patches") Link: https://bugs.debian.org/1008657 Signed-off-by: Sedat Dilek <sedat.di...@gmail.com> --- ...und-to-avoid-breaking-users-of-span-.patch | 390 ++++++++++++++++++ ...orkaround-for-pre-ranges-CTAD-in-std.patch | 78 ++++ debian/patches/series | 4 + 3 files changed, 472 insertions(+) create mode 100644 debian/patches/0001-libc-Add-workaround-to-avoid-breaking-users-of-span-.patch create mode 100644 debian/patches/0002-libc-Re-enable-workaround-for-pre-ranges-CTAD-in-std.patch diff --git a/debian/patches/0001-libc-Add-workaround-to-avoid-breaking-users-of-span-.patch b/debian/patches/0001-libc-Add-workaround-to-avoid-breaking-users-of-span-.patch new file mode 100644 index 000000000000..e59a56057fb2 --- /dev/null +++ b/debian/patches/0001-libc-Add-workaround-to-avoid-breaking-users-of-span-.patch @@ -0,0 +1,390 @@ +From add3ab7f4c8a7f25c2940889d397cbdc9f267666 Mon Sep 17 00:00:00 2001 +From: Louis Dionne <ldionn...@gmail.com> +Date: Mon, 14 Mar 2022 11:50:02 -0400 +Subject: [PATCH] [libc++] Add workaround to avoid breaking users of <span> + when <ranges> are disabled + +Back in 3a208c68942e, we implemented the range-based constructor for <span>. +However, in doing so, we removed a previous non-standard constructor that +we provided before shipping <ranges>. Unfortunately, that breaks code that +was relying on a range-based constructor until we ship all of <ranges>. + +This patch reintroduces the old non-conforming constructors and tests +that were removed in 3a208c68942e and uses them whenever <ranges> is +not provided (e.g. in LLVM 14). This is only a temporary workaround +until we enable <ranges> by default in C++20, which should hopefully +happen by LLVM 15. + +The goal is to cherry-pick this workaround back to the LLVM 14 release +branch, since I suspect the constructor removal may otherwise cause +breakage out there, like the breakage I saw internally. + +We could have avoided this situation by waiting for C++20 to be finalized +before shipping std::span. For example, we could have guarded it with +something like _LIBCPP_HAS_NO_INCOMPLETE_RANGES to prevent users from +accidentally starting to depend on it before it is stable. We did not +have these mechanisms when std::span was first implemented, though. + +NOTE: This is a pretty modified version of d4c39f1ab94 since that one +didn't apply properly onto the release/14.x branch. + +(cherry picked from commit d4c39f1ab94abc1dd4fff1e82dd4fa97265940e1) + +Differential Revision: https://reviews.llvm.org/D121739 +--- + libcxx/include/span | 50 ++++++- + .../containers/views/span.cons/range.pass.cpp | 141 ++++++++++++++++++ + .../views/span.cons/range.verify.cpp | 118 +++++++++++++++ + 3 files changed, 306 insertions(+), 3 deletions(-) + create mode 100644 libcxx/test/libcxx/containers/views/span.cons/range.pass.cpp + create mode 100644 libcxx/test/libcxx/containers/views/span.cons/range.verify.cpp + +diff --git a/libcxx/include/span b/libcxx/include/span +index fd95ecca17f7..b8dbc7e01fd6 100644 +--- a/libcxx/include/span ++++ b/libcxx/include/span +@@ -170,7 +170,25 @@ struct __is_std_span : false_type {}; + template <class _Tp, size_t _Sz> + struct __is_std_span<span<_Tp, _Sz>> : true_type {}; + +-#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) ++#if defined(_LIBCPP_HAS_NO_CONCEPTS) || defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) ++// This is a temporary workaround until we ship <ranges> -- we've unfortunately been ++// shipping <span> before its API was finalized, and we used to provide a constructor ++// from container types that had the requirements below. To avoid breaking code that ++// has started relying on the range-based constructor until we ship all of <ranges>, ++// we emulate the constructor requirements like this. ++template <class _Range, class _ElementType, class = void> ++struct __span_compatible_range : false_type { }; ++ ++template <class _Range, class _ElementType> ++struct __span_compatible_range<_Range, _ElementType, void_t< ++ enable_if_t<!__is_std_span<remove_cvref_t<_Range>>::value>, ++ enable_if_t<!__is_std_array<remove_cvref_t<_Range>>::value>, ++ enable_if_t<!is_array_v<remove_cvref_t<_Range>>>, ++ decltype(data(declval<_Range>())), ++ decltype(size(declval<_Range>())), ++ enable_if_t<is_convertible_v<remove_pointer_t<decltype(data(declval<_Range&>()))>(*)[], _ElementType(*)[]>> ++>> : true_type { }; ++#else + template <class _Range, class _ElementType> + concept __span_compatible_range = + ranges::contiguous_range<_Range> && +@@ -248,7 +266,22 @@ public: + _LIBCPP_INLINE_VISIBILITY + constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} + +-#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) ++#if defined(_LIBCPP_HAS_NO_CONCEPTS) || defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) ++ template <class _Container, class = enable_if_t< ++ __span_compatible_range<_Container, element_type>::value ++ >> ++ _LIBCPP_INLINE_VISIBILITY ++ constexpr explicit span(_Container& __c) : __data{std::data(__c)} { ++ _LIBCPP_ASSERT(std::size(__c) == _Extent, "size mismatch in span's constructor (range)"); ++ } ++ template <class _Container, class = enable_if_t< ++ __span_compatible_range<const _Container, element_type>::value ++ >> ++ _LIBCPP_INLINE_VISIBILITY ++ constexpr explicit span(const _Container& __c) : __data{std::data(__c)} { ++ _LIBCPP_ASSERT(std::size(__c) == _Extent, "size mismatch in span's constructor (range)"); ++ } ++#else + template <__span_compatible_range<element_type> _Range> + _LIBCPP_INLINE_VISIBILITY + constexpr explicit span(_Range&& __r) : __data{ranges::data(__r)} { +@@ -434,7 +467,18 @@ public: + _LIBCPP_INLINE_VISIBILITY + constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} + +-#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) ++#if defined(_LIBCPP_HAS_NO_CONCEPTS) || defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) ++ template <class _Container, class = enable_if_t< ++ __span_compatible_range<_Container, element_type>::value ++ >> ++ _LIBCPP_INLINE_VISIBILITY ++ constexpr span(_Container& __c) : __data(std::data(__c)), __size{std::size(__c)} {} ++ template <class _Container, class = enable_if_t< ++ __span_compatible_range<const _Container, element_type>::value ++ >> ++ _LIBCPP_INLINE_VISIBILITY ++ constexpr span(const _Container& __c) : __data(std::data(__c)), __size{std::size(__c)} {} ++#else + template <__span_compatible_range<element_type> _Range> + _LIBCPP_INLINE_VISIBILITY + constexpr span(_Range&& __r) : __data(ranges::data(__r)), __size{ranges::size(__r)} {} +diff --git a/libcxx/test/libcxx/containers/views/span.cons/range.pass.cpp b/libcxx/test/libcxx/containers/views/span.cons/range.pass.cpp +new file mode 100644 +index 000000000000..efa1001bdb5b +--- /dev/null ++++ b/libcxx/test/libcxx/containers/views/span.cons/range.pass.cpp +@@ -0,0 +1,141 @@ ++//===---------------------------------------------------------------------===// ++// ++// 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 ++ ++// <span> ++ ++// template<class Container> ++// constexpr explicit(Extent != dynamic_extent) span(Container&); ++// template<class Container> ++// constexpr explicit(Extent != dynamic_extent) span(Container const&); ++ ++// This test checks for libc++'s non-conforming temporary extension to std::span ++// to support construction from containers that look like contiguous ranges. ++// ++// This extension is only supported when we don't ship <ranges>, and we can ++// remove it once we get rid of _LIBCPP_HAS_NO_INCOMPLETE_RANGES. ++ ++#include <span> ++#include <cassert> ++#include <string> ++#include <vector> ++ ++#include "test_macros.h" ++ ++// Look ma - I'm a container! ++template <typename T> ++struct IsAContainer { ++ constexpr IsAContainer() : v_{} {} ++ constexpr size_t size() const {return 1;} ++ constexpr T *data() {return &v_;} ++ constexpr const T *data() const {return &v_;} ++ constexpr T *begin() {return &v_;} ++ constexpr const T *begin() const {return &v_;} ++ constexpr T *end() {return &v_ + 1;} ++ constexpr const T *end() const {return &v_ + 1;} ++ ++ constexpr T const *getV() const {return &v_;} // for checking ++ T v_; ++}; ++ ++ ++void checkCV() ++{ ++ std::vector<int> v = {1,2,3}; ++ ++// Types the same ++ { ++ std::span< int> s1{v}; // a span< int> pointing at int. ++ } ++ ++// types different ++ { ++ std::span<const int> s1{v}; // a span<const int> pointing at int. ++ std::span< volatile int> s2{v}; // a span< volatile int> pointing at int. ++ std::span< volatile int> s3{v}; // a span< volatile int> pointing at const int. ++ std::span<const volatile int> s4{v}; // a span<const volatile int> pointing at int. ++ } ++ ++// Constructing a const view from a temporary ++ { ++ std::span<const int> s1{IsAContainer<int>()}; ++ std::span<const int> s3{std::vector<int>()}; ++ (void) s1; ++ (void) s3; ++ } ++} ++ ++ ++template <typename T> ++constexpr bool testConstexprSpan() ++{ ++ constexpr IsAContainer<const T> val{}; ++ std::span<const T> s1{val}; ++ return s1.data() == val.getV() && s1.size() == 1; ++} ++ ++template <typename T> ++constexpr bool testConstexprSpanStatic() ++{ ++ constexpr IsAContainer<const T> val{}; ++ std::span<const T, 1> s1{val}; ++ return s1.data() == val.getV() && s1.size() == 1; ++} ++ ++template <typename T> ++void testRuntimeSpan() ++{ ++ IsAContainer<T> val{}; ++ const IsAContainer<T> cVal; ++ std::span<T> s1{val}; ++ std::span<const T> s2{cVal}; ++ assert(s1.data() == val.getV() && s1.size() == 1); ++ assert(s2.data() == cVal.getV() && s2.size() == 1); ++} ++ ++template <typename T> ++void testRuntimeSpanStatic() ++{ ++ IsAContainer<T> val{}; ++ const IsAContainer<T> cVal; ++ std::span<T, 1> s1{val}; ++ std::span<const T, 1> s2{cVal}; ++ assert(s1.data() == val.getV() && s1.size() == 1); ++ assert(s2.data() == cVal.getV() && s2.size() == 1); ++} ++ ++struct A{}; ++ ++int main(int, char**) ++{ ++ static_assert(testConstexprSpan<int>(), ""); ++ static_assert(testConstexprSpan<long>(), ""); ++ static_assert(testConstexprSpan<double>(), ""); ++ static_assert(testConstexprSpan<A>(), ""); ++ ++ static_assert(testConstexprSpanStatic<int>(), ""); ++ static_assert(testConstexprSpanStatic<long>(), ""); ++ static_assert(testConstexprSpanStatic<double>(), ""); ++ static_assert(testConstexprSpanStatic<A>(), ""); ++ ++ testRuntimeSpan<int>(); ++ testRuntimeSpan<long>(); ++ testRuntimeSpan<double>(); ++ testRuntimeSpan<std::string>(); ++ testRuntimeSpan<A>(); ++ ++ testRuntimeSpanStatic<int>(); ++ testRuntimeSpanStatic<long>(); ++ testRuntimeSpanStatic<double>(); ++ testRuntimeSpanStatic<std::string>(); ++ testRuntimeSpanStatic<A>(); ++ ++ checkCV(); ++ ++ return 0; ++} +diff --git a/libcxx/test/libcxx/containers/views/span.cons/range.verify.cpp b/libcxx/test/libcxx/containers/views/span.cons/range.verify.cpp +new file mode 100644 +index 000000000000..f0edf4f93536 +--- /dev/null ++++ b/libcxx/test/libcxx/containers/views/span.cons/range.verify.cpp +@@ -0,0 +1,118 @@ ++//===---------------------------------------------------------------------===// ++// ++// 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 ++ ++// <span> ++ ++// template<class Container> ++// constexpr explicit(Extent != dynamic_extent) span(Container&); ++// template<class Container> ++// constexpr explicit(Extent != dynamic_extent) span(Container const&); ++ ++// This test checks for libc++'s non-conforming temporary extension to std::span ++// to support construction from containers that look like contiguous ranges. ++// ++// This extension is only supported when we don't ship <ranges>, and we can ++// remove it once we get rid of _LIBCPP_HAS_NO_INCOMPLETE_RANGES. ++ ++#include <span> ++#include <cassert> ++#include <deque> ++#include <forward_list> ++#include <list> ++#include <vector> ++ ++#include "test_macros.h" ++ ++// Look ma - I'm a container! ++template <typename T> ++struct IsAContainer { ++ constexpr IsAContainer() : v_{} {} ++ constexpr size_t size() const {return 1;} ++ constexpr T *data() {return &v_;} ++ constexpr const T *data() const {return &v_;} ++ ++ constexpr const T *getV() const {return &v_;} // for checking ++ T v_; ++}; ++ ++template <typename T> ++struct NotAContainerNoData { ++ size_t size() const {return 0;} ++}; ++ ++template <typename T> ++struct NotAContainerNoSize { ++ const T *data() const {return nullptr;} ++}; ++ ++template <typename T> ++struct NotAContainerPrivate { ++private: ++ size_t size() const {return 0;} ++ const T *data() const {return nullptr;} ++}; ++ ++template<class T, size_t extent, class container> ++std::span<T, extent> createImplicitSpan(container c) { ++ return {c}; // expected-error {{chosen constructor is explicit in copy-initialization}} ++} ++ ++int main(int, char**) ++{ ++ ++// Making non-const spans from const sources (a temporary binds to `const &`) ++ { ++ std::span<int> s1{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} ++ std::span<int> s3{std::vector<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} ++ } ++ ++// Missing size and/or data ++ { ++ std::span<const int> s1{NotAContainerNoData<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}} ++ std::span<const int> s3{NotAContainerNoSize<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}} ++ std::span<const int> s5{NotAContainerPrivate<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}} ++ ++// Again with the standard containers ++ std::span<const int> s11{std::deque<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}} ++ std::span<const int> s13{std::list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}} ++ std::span<const int> s15{std::forward_list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}} ++ } ++ ++// Not the same type ++ { ++ IsAContainer<int> c; ++ std::span<float> s1{c}; // expected-error {{no matching constructor for initialization of 'std::span<float>'}} ++ } ++ ++// CV wrong ++ { ++ IsAContainer<const int> c; ++ IsAContainer<const volatile int> cv; ++ IsAContainer< volatile int> v; ++ ++ std::span< int> s1{c}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} ++ std::span< int> s2{v}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} ++ std::span< int> s3{cv}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} ++ std::span<const int> s4{v}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}} ++ std::span<const int> s5{cv}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}} ++ std::span< volatile int> s6{c}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}} ++ std::span< volatile int> s7{cv}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}} ++ } ++ ++// explicit constructor necessary ++ { ++ IsAContainer<int> c; ++ const IsAContainer<int> cc; ++ ++ createImplicitSpan<int, 1>(c); ++ createImplicitSpan<int, 1>(cc); ++ } ++ ++ return 0; ++} +-- +2.35.1 + diff --git a/debian/patches/0002-libc-Re-enable-workaround-for-pre-ranges-CTAD-in-std.patch b/debian/patches/0002-libc-Re-enable-workaround-for-pre-ranges-CTAD-in-std.patch new file mode 100644 index 000000000000..70666362239f --- /dev/null +++ b/debian/patches/0002-libc-Re-enable-workaround-for-pre-ranges-CTAD-in-std.patch @@ -0,0 +1,78 @@ +From 3f43d803382d57e3fc010ca19833077d1023e9c9 Mon Sep 17 00:00:00 2001 +From: Louis Dionne <ldionn...@gmail.com> +Date: Mon, 21 Mar 2022 17:05:06 -0400 +Subject: [PATCH] [libc++] Re-enable workaround for pre-ranges CTAD in + std::span + +See https://reviews.llvm.org/D121626 for details -- this re-enables the +CTAD we removed, since it does break some stuff as well (even though it's +not nearly as bad as the removed constructors fixed by D121626). + +(cherry picked from commit 6a7f0551178e966a686dd48dfa2ea045a35addef) + +Differential Revision: https://reviews.llvm.org/D122201 +--- + libcxx/include/span | 8 +++++++- + .../test/std/containers/views/span.cons/deduct.pass.cpp | 6 ------ + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/libcxx/include/span b/libcxx/include/span +index b8dbc7e01fd6..f33569031730 100644 +--- a/libcxx/include/span ++++ b/libcxx/include/span +@@ -622,7 +622,13 @@ template<class _Tp, size_t _Sz> + template<class _Tp, size_t _Sz> + span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; + +-#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) ++#if defined(_LIBCPP_HAS_NO_CONCEPTS) || defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) ++template<class _Container> ++ span(_Container&) -> span<typename _Container::value_type>; ++ ++template<class _Container> ++ span(const _Container&) -> span<const typename _Container::value_type>; ++#else + template<ranges::contiguous_range _Range> + span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>; + #endif +diff --git a/libcxx/test/std/containers/views/span.cons/deduct.pass.cpp b/libcxx/test/std/containers/views/span.cons/deduct.pass.cpp +index 81632fed711d..e632feca2e1f 100644 +--- a/libcxx/test/std/containers/views/span.cons/deduct.pass.cpp ++++ b/libcxx/test/std/containers/views/span.cons/deduct.pass.cpp +@@ -6,7 +6,6 @@ + // + //===----------------------------------------------------------------------===// + // UNSUPPORTED: c++03, c++11, c++14, c++17 +-// UNSUPPORTED: libcpp-no-concepts + + // <span> + +@@ -86,7 +85,6 @@ void test_std_array() { + } + } + +-#ifndef _LIBCPP_HAS_NO_INCOMPLETE_RANGES + void test_range_std_container() { + { + std::string str{"ABCDE"}; +@@ -104,17 +102,13 @@ void test_range_std_container() { + assert(s.data() == str.data()); + } + } +-#endif // _LIBCPP_HAS_NO_INCOMPLETE_RANGES + + int main(int, char**) + { + test_iterator_sentinel(); + test_c_array(); + test_std_array(); +- +-#ifndef _LIBCPP_HAS_NO_INCOMPLETE_RANGES + test_range_std_container(); +-#endif // _LIBCPP_HAS_NO_INCOMPLETE_RANGES + + return 0; + } +-- +2.35.1 + diff --git a/debian/patches/series b/debian/patches/series index df956934bc21..fc005ac429df 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -150,3 +150,7 @@ wasm-ld-path.diff python3-scan-build.py revert-update-doc.diff fix-typo.diff + +# libc++ patches from upstream (post version 14.0.0) +0001-libc-Add-workaround-to-avoid-breaking-users-of-span-.patch +0002-libc-Re-enable-workaround-for-pre-ranges-CTAD-in-std.patch -- 2.35.1