summaryrefslogtreecommitdiffstats
path: root/libcxx/test
diff options
context:
space:
mode:
authorLouis Dionne <ldionne@apple.com>2019-02-12 16:06:02 +0000
committerLouis Dionne <ldionne@apple.com>2019-02-12 16:06:02 +0000
commit7232a84e686a0d1bf834a845e4e59c5594ae8957 (patch)
tree195b6c40e1303e25ea40e4e2bc4829a081d7231a /libcxx/test
parentd694160e665eb3cefc93a07af8232aec0b7d2410 (diff)
downloadbcm5719-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')
-rw-r--r--libcxx/test/libcxx/containers/associative/map/at.abort.pass.cpp34
-rw-r--r--libcxx/test/libcxx/containers/associative/map/at.const.abort.pass.cpp34
-rw-r--r--libcxx/test/libcxx/containers/unord/unord.map/at.abort.pass.cpp31
-rw-r--r--libcxx/test/libcxx/containers/unord/unord.map/at.const.abort.pass.cpp31
-rw-r--r--libcxx/test/libcxx/input.output/iostreams.base/ios/iostate.flags/clear.abort.pass.cpp41
-rw-r--r--libcxx/test/libcxx/localization/locales/locale.abort.pass.cpp34
-rw-r--r--libcxx/test/libcxx/localization/locales/locale.category.abort.pass.cpp34
-rw-r--r--libcxx/test/libcxx/localization/locales/use_facet.abort.pass.cpp37
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;
+}
OpenPOWER on IntegriCloud