Skip to content

Commit 2627e8b

Browse files
committed
[libc++] Fix std::variant/std::invoke too eager instantiation
1 parent 1cac2be commit 2627e8b

File tree

4 files changed

+30
-7
lines changed

4 files changed

+30
-7
lines changed

libcxx/include/__type_traits/invoke.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD
6767

6868
#if __has_builtin(__builtin_invoke)
6969

70-
template <class... _Args>
71-
using __invoke_result_t _LIBCPP_NODEBUG = decltype(__builtin_invoke(std::declval<_Args>()...));
72-
7370
template <class, class... _Args>
7471
struct __invoke_result_impl {};
7572

7673
template <class... _Args>
77-
struct __invoke_result_impl<__void_t<__invoke_result_t<_Args...> >, _Args...> {
78-
using type _LIBCPP_NODEBUG = __invoke_result_t<_Args...>;
74+
struct __invoke_result_impl<__void_t<decltype(__builtin_invoke(std::declval<_Args>()...))>, _Args...> {
75+
using type _LIBCPP_NODEBUG = decltype(__builtin_invoke(std::declval<_Args>()...));
7976
};
8077

8178
template <class... _Args>
8279
using __invoke_result _LIBCPP_NODEBUG = __invoke_result_impl<void, _Args...>;
8380

81+
template <class... _Args>
82+
using __invoke_result_t _LIBCPP_NODEBUG = typename __invoke_result<_Args...>::type;
83+
8484
template <class... _Args>
8585
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __invoke_result_t<_Args...> __invoke(_Args&&... __args)
8686
_NOEXCEPT_(noexcept(__builtin_invoke(std::forward<_Args>(__args)...))) {

libcxx/include/string_view

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ public:
320320
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
321321
_LIBCPP_DIAGNOSE_NULLPTR_IF(__len != 0 && __s == nullptr, " if len is not zero")
322322
: __data_(__s), __size_(__len) {
323-
# if _LIBCPP_STD_VER >= 14
323+
# ifndef _LIBCPP_CXX03_LANG
324324
// Allocations must fit in `ptrdiff_t` for pointer arithmetic to work. If `__len` exceeds it, the input
325325
// range could not have been valid. Most likely the caller underflowed some arithmetic and inadvertently
326326
// passed in a negative length.

libcxx/test/libcxx/strings/string.view/assert.ctor.length.pass.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
// REQUIRES: has-unix-headers
10-
// UNSUPPORTED: c++03, c++11
10+
// UNSUPPORTED: c++03
1111
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
1212
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
1313

@@ -17,10 +17,17 @@
1717
#include <string_view>
1818

1919
#include "check_assertion.h"
20+
#include "test_macros.h"
21+
22+
// We're testing for assertions here, so let's not diagnose the misuses at compile time
23+
// FIXME: This should really be in ADDITIONAL_COMPILE_FLAGS, but it that doesn't work due to a Clang bug
24+
TEST_CLANG_DIAGNOSTIC_IGNORED("-Wnonnull")
2025

2126
int main(int, char**) {
2227
char c = 0;
2328
TEST_LIBCPP_ASSERT_FAILURE(
2429
std::string_view(&c, -1), "string_view::string_view(_CharT *, size_t): length does not fit in difference_type");
30+
TEST_LIBCPP_ASSERT_FAILURE(std::string_view(nullptr, 1),
31+
"string_view::string_view(_CharT *, size_t): received nullptr");
2532
return 0;
2633
}

libcxx/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,28 @@ void test_vector_bool() {
173173
assert(std::get<0>(v) == true);
174174
}
175175

176+
struct ConvertibleFromAny {
177+
template <class V>
178+
ConvertibleFromAny(V) {}
179+
};
180+
176181
int main(int, char**) {
177182
test_T_ctor_basic();
178183
test_T_ctor_noexcept();
179184
test_T_ctor_sfinae();
180185
test_no_narrowing_check_for_class_types();
181186
test_construction_with_repeated_types();
182187
test_vector_bool();
188+
189+
{ // Check that the constraints are evaluated lazily (see https://github.com/llvm/llvm-project/issues/151328)
190+
struct Matcher {
191+
Matcher() {}
192+
Matcher(std::variant<ConvertibleFromAny>) {}
193+
};
194+
195+
Matcher vec;
196+
[[maybe_unused]] Matcher m = std::move(vec);
197+
}
198+
183199
return 0;
184200
}

0 commit comments

Comments
 (0)