summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/diagnostics
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2016-06-14 03:45:31 +0000
committerEric Fiselier <eric@efcs.ca>2016-06-14 03:45:31 +0000
commit9778a6d811c346eb9cdd8b6c6c28a915e58d1b67 (patch)
tree3e9731fc91c8e6ffd9c5c94a22723c68fe82bcda /libcxx/test/std/diagnostics
parent10e3d1764a096ca802f65a5bbb9115a75f3d8a83 (diff)
downloadbcm5719-llvm-9778a6d811c346eb9cdd8b6c6c28a915e58d1b67.tar.gz
bcm5719-llvm-9778a6d811c346eb9cdd8b6c6c28a915e58d1b67.zip
Make system_error::message() thread safe. Fixes PR25598.
Summary: system_error::message() uses `strerror` for the generic and system categories. This function is not thread safe. The fix is to use `strerror_r`. It has been available since 2001 for GNU libc and since BSD 4.4 on FreeBSD/OS X. On platforms with GNU libc the extended version is used which always returns a valid string, even if an error occurs. In single-threaded builds `strerror` is still used. See https://llvm.org/bugs/show_bug.cgi?id=25598 Reviewers: majnemer, mclow.lists Subscribers: erik65536, cfe-commits, emaste Differential Revision: http://reviews.llvm.org/D20903 llvm-svn: 272633
Diffstat (limited to 'libcxx/test/std/diagnostics')
-rw-r--r--libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp11
-rw-r--r--libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp12
2 files changed, 23 insertions, 0 deletions
diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp
index 972299936dd..7afbbd06980 100644
--- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp
+++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp
@@ -16,10 +16,21 @@
#include <system_error>
#include <cassert>
#include <string>
+#include <cerrno>
+
+void test_message_leaves_errno_unchanged() {
+ errno = E2BIG; // something that message will never generate
+ const std::error_category& e_cat1 = std::generic_category();
+ e_cat1.message(-1);
+ assert(errno == E2BIG);
+}
int main()
{
const std::error_category& e_cat1 = std::generic_category();
std::string m1 = e_cat1.name();
assert(m1 == "generic");
+ {
+ test_message_leaves_errno_unchanged();
+ }
}
diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp
index b5cb18ad765..8c1e8029252 100644
--- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp
+++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp
@@ -16,6 +16,15 @@
#include <system_error>
#include <cassert>
#include <string>
+#include <cerrno>
+
+
+void test_message_leaves_errno_unchanged() {
+ errno = E2BIG; // something that message will never generate
+ const std::error_category& e_cat1 = std::system_category();
+ e_cat1.message(-1);
+ assert(errno == E2BIG);
+}
int main()
{
@@ -26,4 +35,7 @@ int main()
e_cond = e_cat1.default_error_condition(5000);
assert(e_cond.value() == 5000);
assert(e_cond.category() == std::system_category());
+ {
+ test_message_leaves_errno_unchanged();
+ }
}
OpenPOWER on IntegriCloud