From e0cf3b9a3ca8d80d313d1e2e5b8c70d73d10e933 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 24 Jun 2015 08:44:38 +0000 Subject: Make support for thread-unsafe C functions optional. One of the aspects of CloudABI is that it aims to help you write code that is thread-safe out of the box. This is very important if you want to write libraries that are easy to reuse. For CloudABI we decided to not provide the thread-unsafe functions. So far this is working out pretty well, as thread-unsafety issues are detected really early on. The following patch adds a knob to libc++, _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS, that can be set to disable thread-unsafe functions that can easily be avoided in practice. The following functions are not thread-safe: - : locale handles should be preferred over setlocale(). - : mbrlen(), mbrtowc() and wcrtomb() should be preferred over their non-restartable counterparts. - : asctime(), ctime(), gmtime() and localtime() are not thread-safe. The first two are also deprecated by POSIX. Differential Revision: http://reviews.llvm.org/D8703 Reviewed by: marshall llvm-svn: 240527 --- libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp | 4 +++- libcxx/test/std/depr/depr.c.headers/string_h.pass.cpp | 2 ++ .../language.support/support.runtime/cstdlib.pass.cpp | 4 +++- .../language.support/support.runtime/ctime.pass.cpp | 2 ++ .../test/std/localization/c.locales/clocale.pass.cpp | 6 ++++++ libcxx/test/std/strings/c.strings/cstring.pass.cpp | 2 ++ .../utilities/date.time/asctime.thread-unsafe.fail.cpp | 18 ++++++++++++++++++ .../utilities/date.time/ctime.thread-unsafe.fail.cpp | 18 ++++++++++++++++++ .../utilities/date.time/gmtime.thread-unsafe.fail.cpp | 18 ++++++++++++++++++ .../date.time/localtime.thread-unsafe.fail.cpp | 18 ++++++++++++++++++ 10 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 libcxx/test/std/utilities/date.time/asctime.thread-unsafe.fail.cpp create mode 100644 libcxx/test/std/utilities/date.time/ctime.thread-unsafe.fail.cpp create mode 100644 libcxx/test/std/utilities/date.time/gmtime.thread-unsafe.fail.cpp create mode 100644 libcxx/test/std/utilities/date.time/localtime.thread-unsafe.fail.cpp (limited to 'libcxx/test/std') diff --git a/libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp b/libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp index 98b19c6eb56..47e1527fb17 100644 --- a/libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp +++ b/libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp @@ -71,12 +71,14 @@ int main() static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); wchar_t* pw = 0; const wchar_t* pwc = 0; char* pc = 0; +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS + static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); +#endif static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); } diff --git a/libcxx/test/std/depr/depr.c.headers/string_h.pass.cpp b/libcxx/test/std/depr/depr.c.headers/string_h.pass.cpp index fc7f65d4288..afc784f74b8 100644 --- a/libcxx/test/std/depr/depr.c.headers/string_h.pass.cpp +++ b/libcxx/test/std/depr/depr.c.headers/string_h.pass.cpp @@ -41,7 +41,9 @@ int main() static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS static_assert((std::is_same::value), ""); +#endif static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); diff --git a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp index e14e70e34e4..073949122b0 100644 --- a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp +++ b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp @@ -75,12 +75,14 @@ int main() static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); wchar_t* pw = 0; const wchar_t* pwc = 0; char* pc = 0; +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS + static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); +#endif static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); } diff --git a/libcxx/test/std/language.support/support.runtime/ctime.pass.cpp b/libcxx/test/std/language.support/support.runtime/ctime.pass.cpp index 495d6eb2c66..8c5d2811d8a 100644 --- a/libcxx/test/std/language.support/support.runtime/ctime.pass.cpp +++ b/libcxx/test/std/language.support/support.runtime/ctime.pass.cpp @@ -30,10 +30,12 @@ int main() static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); +#endif char* c1 = 0; const char* c2 = 0; static_assert((std::is_same::value), ""); diff --git a/libcxx/test/std/localization/c.locales/clocale.pass.cpp b/libcxx/test/std/localization/c.locales/clocale.pass.cpp index 3b3e933c551..a90725bfa36 100644 --- a/libcxx/test/std/localization/c.locales/clocale.pass.cpp +++ b/libcxx/test/std/localization/c.locales/clocale.pass.cpp @@ -12,6 +12,8 @@ #include #include +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS + #ifndef LC_ALL #error LC_ALL not defined #endif @@ -36,6 +38,8 @@ #error LC_TIME not defined #endif +#endif // !_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS + #ifndef NULL #error NULL not defined #endif @@ -43,6 +47,8 @@ int main() { std::lconv lc; +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS static_assert((std::is_same::value), ""); +#endif static_assert((std::is_same::value), ""); } diff --git a/libcxx/test/std/strings/c.strings/cstring.pass.cpp b/libcxx/test/std/strings/c.strings/cstring.pass.cpp index 5ed7e6cd11a..20f4050cfbd 100644 --- a/libcxx/test/std/strings/c.strings/cstring.pass.cpp +++ b/libcxx/test/std/strings/c.strings/cstring.pass.cpp @@ -46,7 +46,9 @@ int main() static_assert((std::is_same::value), ""); // static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS static_assert((std::is_same::value), ""); +#endif static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); diff --git a/libcxx/test/std/utilities/date.time/asctime.thread-unsafe.fail.cpp b/libcxx/test/std/utilities/date.time/asctime.thread-unsafe.fail.cpp new file mode 100644 index 00000000000..3a9749e21c5 --- /dev/null +++ b/libcxx/test/std/utilities/date.time/asctime.thread-unsafe.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: libcpp-has-no-thread-unsafe-c-functions + +#include + +int main() { + // asctime is not thread-safe. + std::time_t t = 0; + std::asctime(&t); +} diff --git a/libcxx/test/std/utilities/date.time/ctime.thread-unsafe.fail.cpp b/libcxx/test/std/utilities/date.time/ctime.thread-unsafe.fail.cpp new file mode 100644 index 00000000000..cd246c63152 --- /dev/null +++ b/libcxx/test/std/utilities/date.time/ctime.thread-unsafe.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: libcpp-has-no-thread-unsafe-c-functions + +#include + +int main() { + // ctime is not thread-safe. + std::time_t t = 0; + std::ctime(&t); +} diff --git a/libcxx/test/std/utilities/date.time/gmtime.thread-unsafe.fail.cpp b/libcxx/test/std/utilities/date.time/gmtime.thread-unsafe.fail.cpp new file mode 100644 index 00000000000..a6debcbd98d --- /dev/null +++ b/libcxx/test/std/utilities/date.time/gmtime.thread-unsafe.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: libcpp-has-no-thread-unsafe-c-functions + +#include + +int main() { + // gmtime is not thread-safe. + std::time_t t = 0; + std::gmtime(&t); +} diff --git a/libcxx/test/std/utilities/date.time/localtime.thread-unsafe.fail.cpp b/libcxx/test/std/utilities/date.time/localtime.thread-unsafe.fail.cpp new file mode 100644 index 00000000000..c9e55c8fd3a --- /dev/null +++ b/libcxx/test/std/utilities/date.time/localtime.thread-unsafe.fail.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: libcpp-has-no-thread-unsafe-c-functions + +#include + +int main() { + // localtime is not thread-safe. + std::time_t t = 0; + std::localtime(&t); +} -- cgit v1.2.3