Skip to content

Commit

Permalink
Backport fix for no matching constructor
Browse files Browse the repository at this point in the history
Fixes:
   ../../chrome/common/extensions/chrome_manifest_url_handlers.cc:101:7:
   error: no matching constructor for initialization of 'std::map<const char *, std::reference_wrapper<const absl::optionalstd::string>>' (aka 'map<const char , reference_wrapper<const optional<basic_string>>>')
std::map<const char,

as seen with chromium-109:
   OSSystems/meta-browser#674

Thanks to Raphael Kubo da Costa for finding the commit to be backported!

Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com>
  • Loading branch information
rwmacleod authored and kraj committed Jan 17, 2023
1 parent 8a6558f commit fdb936e
Show file tree
Hide file tree
Showing 2 changed files with 380 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,379 @@
From eec04092d67b94f47439a9065b6bd4cd60165be2 Mon Sep 17 00:00:00 2001
From: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Sat, 5 Dec 2020 19:37:41 -0500
Subject: [PATCH] [libc++] [LWG2993] reference_wrapper<T> conversion from U&&
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Implement the resolution of LWG2993. Replace a deleted constructor
with a constructor that SFINAEs away in appropriate circumstances.
Also, now that the constructor is templated, we must have an
explicit deduction guide to make CTAD work.

Some tests have been merged in from Agustín Bergé's D40259.

Differential Revision: https://reviews.llvm.org/D92725

Upstream-Status: Backport

---
libcxx/docs/Cxx2aStatusIssuesStatus.csv | 2 +-
libcxx/include/__functional_base | 21 ++++-
libcxx/include/functional | 7 +-
.../refwrap.assign/copy_assign.pass.cpp | 20 +++++
.../refwrap/refwrap.const/deduct.pass.cpp | 31 +++++++
.../refwrap.const/type_conv_ctor.pass.cpp | 81 +++++++++++++++++++
.../refwrap.const/type_conv_ctor2.pass.cpp | 61 ++++++++++++++
.../refwrap/refwrap.const/type_ctor.pass.cpp | 17 ++++
8 files changed, 234 insertions(+), 6 deletions(-)
create mode 100644 libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/deduct.pass.cpp
create mode 100644 libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
create mode 100644 libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp

diff --git a/libcxx/docs/Cxx2aStatusIssuesStatus.csv b/libcxx/docs/Cxx2aStatusIssuesStatus.csv
index d2adde69d9d2..b411f12d0ce3 100644
--- a/libcxx/docs/Cxx2aStatusIssuesStatus.csv
+++ b/libcxx/docs/Cxx2aStatusIssuesStatus.csv
@@ -35,7 +35,7 @@
"`2981 <https://wg21.link/LWG2981>`__","Remove redundant deduction guides from standard library","Albuquerque","",""
"`2982 <https://wg21.link/LWG2982>`__","Making size_type consistent in associative container deduction guides","Albuquerque","",""
"`2988 <https://wg21.link/LWG2988>`__","Clause 32 cleanup missed one typename","Albuquerque","",""
-"`2993 <https://wg21.link/LWG2993>`__","reference_wrapper<T> conversion from T&&","Albuquerque","",""
+"`2993 <https://wg21.link/LWG2993>`__","reference_wrapper<T> conversion from T&&","Albuquerque","|Complete|","13.0"
"`2998 <https://wg21.link/LWG2998>`__","Requirements on function objects passed to {``forward_``,}list-specific algorithms","Albuquerque","|Nothing To Do|",""
"`3001 <https://wg21.link/LWG3001>`__","weak_ptr::element_type needs remove_extent_t","Albuquerque","",""
"`3024 <https://wg21.link/LWG3024>`__","variant's copies must be deleted instead of disabled via SFINAE","Albuquerque","|Complete|",""
diff --git a/libcxx/include/__functional_base b/libcxx/include/__functional_base
index 1c02e960d5f0..caa746036bf5 100644
--- a/libcxx/include/__functional_base
+++ b/libcxx/include/__functional_base
@@ -380,13 +380,24 @@ public:
private:
type* __f_;

+#ifndef _LIBCPP_CXX03_LANG
+ static void __fun(_Tp&) _NOEXCEPT;
+ static void __fun(_Tp&&) = delete;
+#endif
+
public:
// construct/copy/destroy
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+#ifdef _LIBCPP_CXX03_LANG
+ _LIBCPP_INLINE_VISIBILITY
reference_wrapper(type& __f) _NOEXCEPT
: __f_(_VSTD::addressof(__f)) {}
-#ifndef _LIBCPP_CXX03_LANG
- private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
+#else
+ template <class _Up, class = _EnableIf<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(_VSTD::declval<_Up>())) >>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(_VSTD::declval<_Up>()))) {
+ type& __f = static_cast<_Up&&>(__u);
+ __f_ = _VSTD::addressof(__f);
+ }
#endif

// access
@@ -511,6 +522,10 @@ public:
#endif // _LIBCPP_CXX03_LANG
};

+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template <class _Tp>
+reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
+#endif

template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
diff --git a/libcxx/include/functional b/libcxx/include/functional
index 67baa5bd4b77..f8565e7e6e67 100644
--- a/libcxx/include/functional
+++ b/libcxx/include/functional
@@ -42,8 +42,8 @@ public:
typedef see below result_type; // Not always defined

// construct/copy/destroy
- reference_wrapper(T&) noexcept;
- reference_wrapper(T&&) = delete; // do not bind to temps
+ template<class U>
+ reference_wrapper(U&&);
reference_wrapper(const reference_wrapper<T>& x) noexcept;

// assignment
@@ -59,6 +59,9 @@ public:
operator() (ArgTypes&&...) const;
};

+template <class T>
+ reference_wrapper(T&) -> reference_wrapper<T>;
+
template <class T> reference_wrapper<T> ref(T& t) noexcept;
template <class T> void ref(const T&& t) = delete;
template <class T> reference_wrapper<T> ref(reference_wrapper<T>t) noexcept;
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp
index f82ee72de915..5058a7477581 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp
@@ -21,6 +21,12 @@ class functor1
{
};

+struct convertible_to_int_ref {
+ int val = 0;
+ operator int&() { return val; }
+ operator int const&() const { return val; }
+};
+
template <class T>
void
test(T& t)
@@ -56,5 +62,19 @@ int main(int, char**)
const int j = 0;
test(j);

+#if TEST_STD_VER >= 11
+ convertible_to_int_ref convi;
+ test(convi);
+ convertible_to_int_ref const convic;
+ test(convic);
+
+ {
+ using Ref = std::reference_wrapper<int>;
+ static_assert((std::is_assignable<Ref&, int&>::value), "");
+ static_assert((!std::is_assignable<Ref&, int>::value), "");
+ static_assert((!std::is_assignable<Ref&, int&&>::value), "");
+ }
+#endif
+
return 0;
}
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/deduct.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/deduct.pass.cpp
new file mode 100644
index 000000000000..4e197e8fc3f3
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/deduct.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// <functional>
+
+// template <class T>
+// reference_wrapper(T&) -> reference_wrapper<T>;
+
+#include <functional>
+
+int main()
+{
+ int i = 0;
+ std::reference_wrapper ri(i);
+ static_assert(std::is_same_v<decltype(ri), std::reference_wrapper<int>>);
+ std::reference_wrapper ri2(ri);
+ static_assert(std::is_same_v<decltype(ri2), std::reference_wrapper<int>>);
+ const int j = 0;
+ std::reference_wrapper rj(j);
+ static_assert(std::is_same_v<decltype(rj), std::reference_wrapper<const int>>);
+ std::reference_wrapper rj2(rj);
+ static_assert(std::is_same_v<decltype(rj2), std::reference_wrapper<const int>>);
+}
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
new file mode 100644
index 000000000000..d8ad18215fb7
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <functional>
+//
+// reference_wrapper
+//
+// template <class U>
+// reference_wrapper(U&&) noexcept(see below);
+
+#include <functional>
+#include <cassert>
+
+struct convertible_to_int_ref {
+ int val = 0;
+ operator int&() { return val; }
+ operator int const&() const { return val; }
+};
+
+template <bool IsNothrow>
+struct nothrow_convertible {
+ int val = 0;
+ operator int&() noexcept(IsNothrow) { return val; }
+};
+
+struct convertible_from_int {
+ convertible_from_int(int) {}
+};
+
+void meow(std::reference_wrapper<int>) {}
+void meow(convertible_from_int) {}
+
+int gi;
+std::reference_wrapper<int> purr() { return gi; };
+
+template <class T>
+void
+test(T& t)
+{
+ std::reference_wrapper<T> r(t);
+ assert(&r.get() == &t);
+}
+
+void f() {}
+
+int main()
+{
+ convertible_to_int_ref convi;
+ test(convi);
+ convertible_to_int_ref const convic;
+ test(convic);
+
+ {
+ using Ref = std::reference_wrapper<int>;
+ static_assert((std::is_nothrow_constructible<Ref, nothrow_convertible<true>>::value), "");
+ static_assert((!std::is_nothrow_constructible<Ref, nothrow_convertible<false>>::value), "");
+ }
+
+ {
+ meow(0);
+ (true) ? purr() : 0;
+ }
+
+#ifdef __cpp_deduction_guides
+ {
+ int i = 0;
+ std::reference_wrapper ri(i);
+ static_assert((std::is_same<decltype(ri), std::reference_wrapper<int>>::value), "" );
+ const int j = 0;
+ std::reference_wrapper rj(j);
+ static_assert((std::is_same<decltype(rj), std::reference_wrapper<const int>>::value), "" );
+ }
+#endif
+}
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp
new file mode 100644
index 000000000000..debdc12c8588
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <functional>
+//
+// reference_wrapper
+//
+// template <class U>
+// reference_wrapper(U&&);
+
+#include <functional>
+#include <cassert>
+
+struct B {} b;
+
+struct A1 {
+ operator B& () const { return b; }
+};
+struct A2 {
+ operator B& () const noexcept { return b; }
+};
+
+int main()
+{
+ {
+ std::reference_wrapper<B> b1 = A1();
+ assert(&b1.get() == &b);
+ b1 = A1();
+ assert(&b1.get() == &b);
+
+ static_assert(std::is_convertible<A1, std::reference_wrapper<B>>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::reference_wrapper<B>, A1>::value, "");
+#if TEST_STD_VER >= 20
+ static_assert(!std::is_nothrow_convertible_v<A1, std::reference_wrapper<B>>);
+#endif
+ static_assert(std::is_assignable<std::reference_wrapper<B>, A1>::value, "");
+ static_assert(!std::is_nothrow_assignable<std::reference_wrapper<B>, A1>::value, "");
+ }
+
+ {
+ std::reference_wrapper<B> b2 = A2();
+ assert(&b2.get() == &b);
+ b2 = A2();
+ assert(&b2.get() == &b);
+
+ static_assert(std::is_convertible<A2, std::reference_wrapper<B>>::value, "");
+ static_assert(std::is_nothrow_constructible<std::reference_wrapper<B>, A2>::value, "");
+#if TEST_STD_VER >= 20
+ static_assert(std::is_nothrow_convertible_v<A2, std::reference_wrapper<B>>);
+#endif
+ static_assert(std::is_assignable<std::reference_wrapper<B>, A2>::value, "");
+ static_assert(std::is_nothrow_assignable<std::reference_wrapper<B>, A2>::value, "");
+ }
+}
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp
index 4d536a20411d..af2273452612 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp
@@ -14,6 +14,7 @@

#include <functional>
#include <cassert>
+#include <type_traits>

#include "test_macros.h"

@@ -43,5 +44,21 @@ int main(int, char**)
const int j = 0;
test(j);

+ {
+ using Ref = std::reference_wrapper<int>;
+ static_assert((std::is_constructible<Ref, int&>::value), "");
+ static_assert((!std::is_constructible<Ref, int>::value), "");
+ static_assert((!std::is_constructible<Ref, int&&>::value), "");
+ }
+
+#if TEST_STD_VER >= 11
+ {
+ using Ref = std::reference_wrapper<int>;
+ static_assert((std::is_nothrow_constructible<Ref, int&>::value), "");
+ static_assert((!std::is_nothrow_constructible<Ref, int>::value), "");
+ static_assert((!std::is_nothrow_constructible<Ref, int&&>::value), "");
+ }
+#endif
+
return 0;
}
--
2.34.1

1 change: 1 addition & 0 deletions recipes-devtools/clang/common.inc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ SRC_URI = "\
file://0033-compiler-rt-Link-scudo-with-SANITIZER_CXX_ABI_LIBRAR.patch \
file://0034-CMake-Installable-find-modules-for-terminfo-and-libf.patch \
file://0035-llvm-Do-not-use-standard-search-paths-in-find_librar.patch \
file://0036-libc-LWG2993-reference_wrapper-T-conversion-from-U.patch \
"
# Fallback to no-PIE if not set
GCCPIE ??= ""
Expand Down

0 comments on commit fdb936e

Please sign in to comment.