diff options
| author | Louis Dionne <ldionne@apple.com> | 2019-02-12 16:06:02 +0000 |
|---|---|---|
| committer | Louis Dionne <ldionne@apple.com> | 2019-02-12 16:06:02 +0000 |
| commit | 7232a84e686a0d1bf834a845e4e59c5594ae8957 (patch) | |
| tree | 195b6c40e1303e25ea40e4e2bc4829a081d7231a /libcxx/test | |
| parent | d694160e665eb3cefc93a07af8232aec0b7d2410 (diff) | |
| download | bcm5719-llvm-7232a84e686a0d1bf834a845e4e59c5594ae8957.tar.gz bcm5719-llvm-7232a84e686a0d1bf834a845e4e59c5594ae8957.zip | |
[libc++] Avoid UB in the no-exceptions mode in a few places
Summary:
A few places in the library seem to behave unexpectedly when the library
is compiled or used with exceptions disabled. For example, not throwing
an exception when a pointer is NULL can lead us to dereference the pointer
later on, which is UB. This patch fixes such occurences.
It's hard to tell whether there are other places where the no-exceptions
mode misbehaves like this, because the replacement for throwing an
exception does not always seem to be abort()ing, but at least this
patch will improve the situation somewhat.
See http://lists.llvm.org/pipermail/libcxx-dev/2019-January/000172.html
Reviewers: mclow.lists, EricWF
Subscribers: christof, jkorous, dexonsmith, libcxx-commits
Differential Revision: https://reviews.llvm.org/D57761
llvm-svn: 353850
Diffstat (limited to 'libcxx/test')
8 files changed, 276 insertions, 0 deletions
diff --git a/libcxx/test/libcxx/containers/associative/map/at.abort.pass.cpp b/libcxx/test/libcxx/containers/associative/map/at.abort.pass.cpp new file mode 100644 index 00000000000..d34f48f4dae --- /dev/null +++ b/libcxx/test/libcxx/containers/associative/map/at.abort.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <map> + +// class map + +// mapped_type& at(const key_type& k); + +// Make sure we abort() when exceptions are disabled and we fetch a key that +// is not in the map. + +// REQUIRES: libcpp-no-exceptions + +#include <csignal> +#include <cstdlib> +#include <map> + + +void exit_success(int) { + std::_Exit(EXIT_SUCCESS); +} + +int main(int, char**) { + std::signal(SIGABRT, exit_success); + std::map<int, int> map; + map.at(1); + return EXIT_FAILURE; +} diff --git a/libcxx/test/libcxx/containers/associative/map/at.const.abort.pass.cpp b/libcxx/test/libcxx/containers/associative/map/at.const.abort.pass.cpp new file mode 100644 index 00000000000..705ada86936 --- /dev/null +++ b/libcxx/test/libcxx/containers/associative/map/at.const.abort.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <map> + +// class map + +// const mapped_type& at(const key_type& k) const; + +// Make sure we abort() when exceptions are disabled and we fetch a key that +// is not in the map. + +// REQUIRES: libcpp-no-exceptions + +#include <csignal> +#include <cstdlib> +#include <map> + + +void exit_success(int) { + std::_Exit(EXIT_SUCCESS); +} + +int main(int, char**) { + std::signal(SIGABRT, exit_success); + std::map<int, int> const map; + map.at(1); + return EXIT_FAILURE; +} diff --git a/libcxx/test/libcxx/containers/unord/unord.map/at.abort.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.map/at.abort.pass.cpp new file mode 100644 index 00000000000..b65af169b9b --- /dev/null +++ b/libcxx/test/libcxx/containers/unord/unord.map/at.abort.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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// class unordered_map + +// mapped_type& at(const key_type& k); + +// Make sure we abort() when exceptions are disabled and we fetch a key that +// is not in the map. + +// REQUIRES: libcpp-no-exceptions +// UNSUPPORTED: c++98, c++03 + +#include <csignal> +#include <cstdlib> +#include <unordered_map> + + +int main(int, char**) { + std::signal(SIGABRT, [](int) { std::_Exit(EXIT_SUCCESS); }); + std::unordered_map<int, int> map; + map.at(1); + return EXIT_FAILURE; +} diff --git a/libcxx/test/libcxx/containers/unord/unord.map/at.const.abort.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.map/at.const.abort.pass.cpp new file mode 100644 index 00000000000..af2a2cd7691 --- /dev/null +++ b/libcxx/test/libcxx/containers/unord/unord.map/at.const.abort.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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// class unordered_map + +// const mapped_type& at(const key_type& k) const; + +// Make sure we abort() when exceptions are disabled and we fetch a key that +// is not in the map. + +// REQUIRES: libcpp-no-exceptions +// UNSUPPORTED: c++98, c++03 + +#include <csignal> +#include <cstdlib> +#include <unordered_map> + + +int main(int, char**) { + std::signal(SIGABRT, [](int) { std::_Exit(EXIT_SUCCESS); }); + std::unordered_map<int, int> const map; + map.at(1); + return EXIT_FAILURE; +} diff --git a/libcxx/test/libcxx/input.output/iostreams.base/ios/iostate.flags/clear.abort.pass.cpp b/libcxx/test/libcxx/input.output/iostreams.base/ios/iostate.flags/clear.abort.pass.cpp new file mode 100644 index 00000000000..e6dc1c98100 --- /dev/null +++ b/libcxx/test/libcxx/input.output/iostreams.base/ios/iostate.flags/clear.abort.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 +// +//===----------------------------------------------------------------------===// + +// <ios> + +// template <class charT, class traits> class basic_ios + +// void clear(iostate state); + +// Make sure that we abort() when exceptions are disabled and the exception +// flag is set for the iostate we pass to clear(). + +// REQUIRES: libcpp-no-exceptions + +#include <csignal> +#include <cstdlib> +#include <ios> +#include <streambuf> + + +void exit_success(int) { + std::_Exit(EXIT_SUCCESS); +} + +struct testbuf : public std::streambuf {}; + +int main(int, char**) { + std::signal(SIGABRT, exit_success); + + testbuf buf; + std::ios ios(&buf); + ios.exceptions(std::ios::badbit); + ios.clear(std::ios::badbit); + + return EXIT_FAILURE; +} diff --git a/libcxx/test/libcxx/localization/locales/locale.abort.pass.cpp b/libcxx/test/libcxx/localization/locales/locale.abort.pass.cpp new file mode 100644 index 00000000000..5817ebdfda5 --- /dev/null +++ b/libcxx/test/libcxx/localization/locales/locale.abort.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <locale> + +// class locale; + +// explicit locale( const char* std_name ); + +// REQUIRES: libcpp-no-exceptions + +// Make sure we abort() when we construct a locale with a null name and +// exceptions are disabled. + +#include <csignal> +#include <cstdlib> +#include <locale> + + +void exit_success(int) { + std::_Exit(EXIT_SUCCESS); +} + +int main(int, char**) { + std::signal(SIGABRT, exit_success); + std::locale loc(NULL); + (void)loc; + return EXIT_FAILURE; +} diff --git a/libcxx/test/libcxx/localization/locales/locale.category.abort.pass.cpp b/libcxx/test/libcxx/localization/locales/locale.category.abort.pass.cpp new file mode 100644 index 00000000000..cf50415a2c9 --- /dev/null +++ b/libcxx/test/libcxx/localization/locales/locale.category.abort.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <locale> + +// class locale; + +// locale(const locale& other, const char* std_name, category cat); + +// REQUIRES: libcpp-no-exceptions + +// Make sure we abort() when we construct a locale with a null name and +// exceptions are disabled. + +#include <csignal> +#include <cstdlib> +#include <locale> + + +void exit_success(int) { + std::_Exit(EXIT_SUCCESS); +} + +int main(int, char**) { + std::signal(SIGABRT, exit_success); + std::locale loc(std::locale(), NULL, std::locale::ctype); + (void)loc; + return EXIT_FAILURE; +} diff --git a/libcxx/test/libcxx/localization/locales/use_facet.abort.pass.cpp b/libcxx/test/libcxx/localization/locales/use_facet.abort.pass.cpp new file mode 100644 index 00000000000..64700eab9d1 --- /dev/null +++ b/libcxx/test/libcxx/localization/locales/use_facet.abort.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <locale> + +// template <class Facet> const Facet& use_facet(const locale& loc); + +// REQUIRES: libcpp-no-exceptions + +// Make sure we abort() when we pass a facet not associated to the locale to +// use_facet() and exceptions are disabled. + +#include <csignal> +#include <cstdlib> +#include <locale> + + +struct my_facet : public std::locale::facet { + static std::locale::id id; +}; + +std::locale::id my_facet::id; + +void exit_success(int) { + std::_Exit(EXIT_SUCCESS); +} + +int main(int, char**) { + std::signal(SIGABRT, exit_success); + std::use_facet<my_facet>(std::locale()); + return EXIT_FAILURE; +} |

