diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv --- a/libcxx/docs/Status/Cxx2bIssues.csv +++ b/libcxx/docs/Status/Cxx2bIssues.csv @@ -186,6 +186,7 @@ "`3721 `__","Allow an ``arg-id`` with a value of zero for ``width`` in ``std-format-spec``","July 2022","|Complete|","16.0","|format|" "`3724 `__","``decay-copy`` should be constrained","July 2022","|Complete|","14.0" "","","","","" -"`3645 `__","``resize_and_overwrite`` is overspecified to call its callback with lvalues","Not voted in","|Complete|","14.0","" +"`3629 `__","``make_error_code`` and ``make_error_condition`` are customization points","Not voted in","|Complete|","16.0","" "`3631 `__","``basic_format_arg(T&&)`` should use ``remove_cvref_t`` throughout","Not voted in","|Complete|","15.0","" +"`3645 `__","``resize_and_overwrite`` is overspecified to call its callback with lvalues","Not voted in","|Complete|","14.0","" "","","","","" diff --git a/libcxx/include/system_error b/libcxx/include/system_error --- a/libcxx/include/system_error +++ b/libcxx/include/system_error @@ -256,6 +256,13 @@ _LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT; _LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT; +namespace __adl_only { + // Those cause ADL to trigger but they are not viable candidates, + // so they are never actually selected. + void make_error_condition() = delete; + void make_error_code() = delete; +} // namespace __adl_only + class _LIBCPP_TYPE_VIS error_condition { int __val_; @@ -273,7 +280,10 @@ error_condition(_Ep __e, typename enable_if::value>::type* = nullptr ) _NOEXCEPT - {*this = make_error_condition(__e);} + { + using __adl_only::make_error_condition; + *this = make_error_condition(__e); + } _LIBCPP_INLINE_VISIBILITY void assign(int __val, const error_category& __cat) _NOEXCEPT @@ -290,7 +300,11 @@ error_condition& >::type operator=(_Ep __e) _NOEXCEPT - {*this = make_error_condition(__e); return *this;} + { + using __adl_only::make_error_condition; + *this = make_error_condition(__e); + return *this; + } _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT @@ -336,7 +350,10 @@ error_code(_Ep __e, typename enable_if::value>::type* = nullptr ) _NOEXCEPT - {*this = make_error_code(__e);} + { + using __adl_only::make_error_code; + *this = make_error_code(__e); + } _LIBCPP_INLINE_VISIBILITY void assign(int __val, const error_category& __cat) _NOEXCEPT @@ -353,7 +370,11 @@ error_code& >::type operator=(_Ep __e) _NOEXCEPT - {*this = make_error_code(__e); return *this;} + { + using __adl_only::make_error_code; + *this = make_error_code(__e); + return *this; + } _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.constructors/lwg3629.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.constructors/lwg3629.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.constructors/lwg3629.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// class error_code + +// template error_code(E e); + +// Regression test for https://github.com/llvm/llvm-project/issues/57614 + +int make_error_code; // It's important that this comes before + +#include +#include +#include + +namespace user { + enum Err {}; + + std::error_code make_error_code(Err) { return std::error_code(42, std::generic_category()); } +} + +namespace std { + template <> + struct is_error_code_enum : true_type {}; +} + +int main(int, char**) { + std::error_code e((user::Err())); + assert(e.value() == 42); + assert(e.category() == std::generic_category()); + + return 0; +} diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.modifiers/lwg3629.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.modifiers/lwg3629.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.modifiers/lwg3629.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// class error_code + +// template error_code& operator=(E e); + +// Regression test for https://github.com/llvm/llvm-project/issues/57614 + +int make_error_code; // It's important that this comes before + +#include +#include +#include + +namespace user { + enum Err {}; + + std::error_code make_error_code(Err) { return std::error_code(42, std::generic_category()); } +} + +namespace std { + template <> + struct is_error_code_enum : true_type {}; +} + +int main(int, char**) { + std::error_code e; + e = user::Err(); + assert(e.value() == 42); + assert(e.category() == std::generic_category()); + + return 0; +} diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcondition/syserr.errcondition.constructors/lwg3629.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcondition/syserr.errcondition.constructors/lwg3629.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcondition/syserr.errcondition.constructors/lwg3629.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// class error_condition + +// template error_condition(E e); + +// Regression test for https://github.com/llvm/llvm-project/issues/57614 + +int make_error_condition; // It's important that this comes before + +#include +#include +#include + +namespace user { + enum Err {}; + + std::error_condition make_error_condition(Err) { return std::error_condition(42, std::generic_category()); } +} + +namespace std { + template <> + struct is_error_condition_enum : true_type {}; +} + +int main(int, char**) { + std::error_condition e((user::Err())); + assert(e.value() == 42); + assert(e.category() == std::generic_category()); + + return 0; +} diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcondition/syserr.errcondition.modifiers/lwg3629.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcondition/syserr.errcondition.modifiers/lwg3629.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcondition/syserr.errcondition.modifiers/lwg3629.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// class error_condition + +// template error_condition& operator=(E e); + +// Regression test for https://github.com/llvm/llvm-project/issues/57614 + +int make_error_condition; // It's important that this comes before + +#include +#include +#include + +#include "test_macros.h" + +namespace user { + enum Err {}; + + std::error_condition make_error_condition(Err) { return std::error_condition(42, std::generic_category()); } +} + +namespace std { + template <> + struct is_error_condition_enum : true_type {}; +} + +int main(int, char**) { + std::error_condition e; + e = user::Err(); + assert(e.value() == 42); + assert(e.category() == std::generic_category()); + return 0; +}