diff options
Diffstat (limited to 'libcxx')
18 files changed, 191 insertions, 160 deletions
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index cd6583c..ed54751 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -535,6 +535,7 @@ set(files __locale_dir/time.h __locale_dir/wbuffer_convert.h __locale_dir/wstring_convert.h + __log_hardening_failure __math/abs.h __math/copysign.h __math/error_functions.h diff --git a/libcxx/include/__config b/libcxx/include/__config index 19398dd..3fe377a 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -207,6 +207,7 @@ _LIBCPP_HARDENING_MODE_DEBUG # define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY # define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY # define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY +# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY # if defined(__MVS__) # include <features.h> // for __NATIVE_ASCII_F diff --git a/libcxx/include/__log_hardening_failure b/libcxx/include/__log_hardening_failure new file mode 100644 index 0000000..d180530 --- /dev/null +++ b/libcxx/include/__log_hardening_failure @@ -0,0 +1,42 @@ +// -*- 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___LOG_HARDENING_FAILURE +#define _LIBCPP___LOG_HARDENING_FAILURE + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// Hardening logging is not available in the C++03 mode; moreover, it is currently only available in the experimental +// library. +#if _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC && !defined(_LIBCPP_CXX03_LANG) + +_LIBCPP_BEGIN_NAMESPACE_STD + +// This function should never be called directly from the code -- it should only be called through the +// `_LIBCPP_LOG_HARDENING_FAILURE` macro. +[[__gnu__::__cold__]] _LIBCPP_EXPORTED_FROM_ABI void __log_hardening_failure(const char* __message) noexcept; + +// _LIBCPP_LOG_HARDENING_FAILURE(message) +// +// This macro is used to log an error without terminating the program (as is the case for hardening failures if the +// `observe` assertion semantic is used). + +# if !defined(_LIBCPP_LOG_HARDENING_FAILURE) +# define _LIBCPP_LOG_HARDENING_FAILURE(__message) ::std::__log_hardening_failure(__message) +# endif // !defined(_LIBCPP_LOG_HARDENING_FAILURE) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC && !defined(_LIBCPP_CXX03_LANG) + +#endif // _LIBCPP___LOG_HARDENING_FAILURE diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index ac49720..117556e 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -2355,6 +2355,9 @@ module std [system] { header "__std_mbstate_t.h" export * } + module log_hardening_failure { + header "__log_hardening_failure" + } module verbose_abort { header "__verbose_abort" } diff --git a/libcxx/include/tuple b/libcxx/include/tuple index 662d926..1623702 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -443,12 +443,6 @@ public: template <class... _Tp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swallow(_Tp&&...) _NOEXCEPT {} -template <class _Tp> -struct __all_default_constructible; - -template <class... _Tp> -struct __all_default_constructible<__tuple_types<_Tp...>> : __all<is_default_constructible<_Tp>::value...> {}; - // __tuple_impl template <class _Indx, class... _Tp> diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt index 97fe57a..f59fe0e 100644 --- a/libcxx/src/CMakeLists.txt +++ b/libcxx/src/CMakeLists.txt @@ -309,6 +309,7 @@ add_custom_target(cxx DEPENDS ${LIBCXX_BUILD_TARGETS}) # Build the experimental static library set(LIBCXX_EXPERIMENTAL_SOURCES experimental/keep.cpp + experimental/log_hardening_failure.cpp ) if (LIBCXX_PSTL_BACKEND STREQUAL "libdispatch") diff --git a/libcxx/src/experimental/log_hardening_failure.cpp b/libcxx/src/experimental/log_hardening_failure.cpp new file mode 100644 index 0000000..f836c15 --- /dev/null +++ b/libcxx/src/experimental/log_hardening_failure.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 +// +//===----------------------------------------------------------------------===// + +#include <__config> +#include <__log_hardening_failure> +#include <cstdio> + +#ifdef __BIONIC__ +# include <syslog.h> +#endif // __BIONIC__ + +_LIBCPP_BEGIN_NAMESPACE_STD + +void __log_hardening_failure(const char* message) noexcept { + // Always log the message to `stderr` in case the platform-specific system calls fail. + std::fputs(message, stderr); + +#if defined(__BIONIC__) + // Show error in logcat. The latter two arguments are ignored on Android. + openlog("libc++", 0, 0); + syslog(LOG_CRIT, "%s", message); + closelog(); +#endif +} + +_LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/libcxx/assertions/log_hardening_failure.pass.cpp b/libcxx/test/libcxx/assertions/log_hardening_failure.pass.cpp new file mode 100644 index 0000000..dda071b --- /dev/null +++ b/libcxx/test/libcxx/assertions/log_hardening_failure.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Basic smoke test for `__log_hardening_failure`. +// +// UNSUPPORTED: c++03 +// UNSUPPORTED: libcpp-has-no-experimental-hardening-observe-semantic + +#include <__log_hardening_failure> + +#include "test_macros.h" + +ASSERT_NOEXCEPT(std::__log_hardening_failure("")); + +int main(int, char**) { + std::__log_hardening_failure("Some message"); + // It's difficult to properly test platform-specific logging behavior of the function; just make sure it exists and + // can be called at runtime. + + return 0; +} diff --git a/libcxx/test/libcxx/containers/sequences/forwardlist/bool-conversion.pass.cpp b/libcxx/test/libcxx/containers/sequences/forwardlist/bool-conversion.pass.cpp deleted file mode 100644 index 237b0f1..0000000 --- a/libcxx/test/libcxx/containers/sequences/forwardlist/bool-conversion.pass.cpp +++ /dev/null @@ -1,37 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// REQUIRES: std-at-least-c++20 - -// <forward_list> - -// This test shows the effect of implementing `LWG4135`, before it this code -// was ill-formed, as the predicate is not bool. `LWG4135` suggests that -// std::erase explicitly specifying the lambda's return type as bool. - -#include <forward_list> - -struct Bool { - Bool() = default; - Bool(const Bool&) = delete; - operator bool() const { return true; } -}; - -struct Int { - Bool& operator==(Int) const { - static Bool b; - return b; - } -}; - -int main(int, char**) { - std::forward_list<Int> l; - std::erase(l, Int{}); - - return 0; -} diff --git a/libcxx/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp deleted file mode 100644 index 9e3fb88..0000000 --- a/libcxx/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp +++ /dev/null @@ -1,56 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// <vector> - -// template <class InputIter> vector(InputIter first, InputIter last); - -#include <vector> -#include <cassert> - -#include "test_macros.h" -#include "min_allocator.h" - -void test_ctor_under_alloc() { - int arr1[] = {42}; - int arr2[] = {1, 101, 42}; - { - typedef std::vector<int, cpp03_allocator<int> > C; - typedef C::allocator_type Alloc; - { - Alloc::construct_called = false; - C v(arr1, arr1 + 1); - assert(Alloc::construct_called); - } - { - Alloc::construct_called = false; - C v(arr2, arr2 + 3); - assert(Alloc::construct_called); - } - } - { - typedef std::vector<int, cpp03_overload_allocator<int> > C; - typedef C::allocator_type Alloc; - { - Alloc::construct_called = false; - C v(arr1, arr1 + 1); - assert(Alloc::construct_called); - } - { - Alloc::construct_called = false; - C v(arr2, arr2 + 3); - assert(Alloc::construct_called); - } - } -} - -int main(int, char**) { - test_ctor_under_alloc(); - - return 0; -} diff --git a/libcxx/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp deleted file mode 100644 index fa1bd2d..0000000 --- a/libcxx/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// <vector> - -// template <class InputIter> vector(InputIter first, InputIter last, -// const allocator_type& a); - -#include <vector> -#include <cassert> - -#include "test_macros.h" -#include "min_allocator.h" - -void test_ctor_under_alloc() { - int arr1[] = {42}; - int arr2[] = {1, 101, 42}; - { - typedef std::vector<int, cpp03_allocator<int> > C; - typedef C::allocator_type Alloc; - Alloc a; - { - Alloc::construct_called = false; - C v(arr1, arr1 + 1, a); - assert(Alloc::construct_called); - } - { - Alloc::construct_called = false; - C v(arr2, arr2 + 3, a); - assert(Alloc::construct_called); - } - } - { - typedef std::vector<int, cpp03_overload_allocator<int> > C; - typedef C::allocator_type Alloc; - Alloc a; - { - Alloc::construct_called = false; - C v(arr1, arr1 + 1, a); - assert(Alloc::construct_called); - } - { - Alloc::construct_called = false; - C v(arr2, arr2 + 3, a); - assert(Alloc::construct_called); - } - } -} - -int main(int, char**) { - test_ctor_under_alloc(); - - return 0; -} diff --git a/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp b/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp index 3cf497d..3d97446 100644 --- a/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp +++ b/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp @@ -29,3 +29,7 @@ #if !_LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM # error "-fexperimental-library should enable the syncstream header" #endif + +#if !_LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC +# error "-fexperimental-library should allow using the Hardening observe semantic" +#endif diff --git a/libcxx/test/libcxx/containers/associative/map/find.modules.compile.pass.mm b/libcxx/test/std/containers/associative/map/find.modules.compile.pass.mm index 82b1c494..82b1c494 100644 --- a/libcxx/test/libcxx/containers/associative/map/find.modules.compile.pass.mm +++ b/libcxx/test/std/containers/associative/map/find.modules.compile.pass.mm diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp index 86d7769..3031276 100644 --- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp +++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp @@ -69,6 +69,25 @@ TEST_CONSTEXPR_CXX26 bool test() { test<std::forward_list<long>>(); test<std::forward_list<double>>(); + { // Ensure that the result of operator== is converted to bool + // See LWG4135. + struct Bool { + Bool() = default; + Bool(const Bool&) = delete; + operator bool() const { return true; } + }; + + struct Int { + Bool& operator==(Int) const { + static Bool b; + return b; + } + }; + + std::forward_list<Int> l; + std::erase(l, Int{}); + } + return true; } diff --git a/libcxx/test/libcxx/containers/sequences/vector/erase.modules.compile.pass.mm b/libcxx/test/std/containers/sequences/vector/erase.modules.compile.pass.mm index d270673..d270673 100644 --- a/libcxx/test/libcxx/containers/sequences/vector/erase.modules.compile.pass.mm +++ b/libcxx/test/std/containers/sequences/vector/erase.modules.compile.pass.mm diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp index bac2ea2..6549735 100644 --- a/libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp @@ -127,9 +127,9 @@ TEST_CONSTEXPR_CXX20 void emplaceable_concept_tests() { } void test_ctor_under_alloc() { -#if TEST_STD_VER >= 11 int arr1[] = {42}; int arr2[] = {1, 101, 42}; +#if TEST_STD_VER >= 11 { using C = TCT::vector<>; using It = forward_iterator<int*>; @@ -155,6 +155,35 @@ void test_ctor_under_alloc() { } } #endif + // FIXME: This is mostly the same test as above, just worse. They should be merged. + { + typedef std::vector<int, cpp03_allocator<int> > C; + typedef C::allocator_type Alloc; + { + Alloc::construct_called = false; + C v(arr1, arr1 + 1); + assert(Alloc::construct_called); + } + { + Alloc::construct_called = false; + C v(arr2, arr2 + 3); + assert(Alloc::construct_called); + } + } + { + typedef std::vector<int, cpp03_overload_allocator<int> > C; + typedef C::allocator_type Alloc; + { + Alloc::construct_called = false; + C v(arr1, arr1 + 1); + assert(Alloc::construct_called); + } + { + Alloc::construct_called = false; + C v(arr2, arr2 + 3); + assert(Alloc::construct_called); + } + } } // In C++03, you can't instantiate a template with a local type. diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp index de32504..019f427 100644 --- a/libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp @@ -141,9 +141,9 @@ TEST_CONSTEXPR_CXX20 void emplaceable_concept_tests() { } void test_ctor_under_alloc() { -#if TEST_STD_VER >= 11 int arr1[] = {42}; int arr2[] = {1, 101, 42}; +#if TEST_STD_VER >= 11 { using C = TCT::vector<>; using It = forward_iterator<int*>; @@ -173,6 +173,37 @@ void test_ctor_under_alloc() { } } #endif + // FIXME: This is mostly the same test as above, just worse. They should be merged. + { + typedef std::vector<int, cpp03_allocator<int> > C; + typedef C::allocator_type Alloc; + Alloc a; + { + Alloc::construct_called = false; + C v(arr1, arr1 + 1, a); + assert(Alloc::construct_called); + } + { + Alloc::construct_called = false; + C v(arr2, arr2 + 3, a); + assert(Alloc::construct_called); + } + } + { + typedef std::vector<int, cpp03_overload_allocator<int> > C; + typedef C::allocator_type Alloc; + Alloc a; + { + Alloc::construct_called = false; + C v(arr1, arr1 + 1, a); + assert(Alloc::construct_called); + } + { + Alloc::construct_called = false; + C v(arr2, arr2 + 3, a); + assert(Alloc::construct_called); + } + } } TEST_CONSTEXPR_CXX20 bool test() { diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py index adfb2a9..93cf29b 100644 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -361,6 +361,7 @@ DEFAULT_PARAMETERS = [ AddFeature("libcpp-has-no-incomplete-pstl"), AddFeature("libcpp-has-no-experimental-tzdb"), AddFeature("libcpp-has-no-experimental-syncstream"), + AddFeature("libcpp-has-no-experimental-hardening-observe-semantic"), ], ), # TODO: This can be improved once we use a version of GoogleBenchmark that supports the dry-run mode. |