diff options
| author | Howard Hinnant <hhinnant@apple.com> | 2010-12-02 16:45:21 +0000 |
|---|---|---|
| committer | Howard Hinnant <hhinnant@apple.com> | 2010-12-02 16:45:21 +0000 |
| commit | 1596c4531b3950f4c883013cb51182ad40884633 (patch) | |
| tree | 969833db70ead1f9cf8f6d0ec88590ab60858fbe | |
| parent | cdae9242fa11b0bb9a575dc4632fc3008c662339 (diff) | |
| download | bcm5719-llvm-1596c4531b3950f4c883013cb51182ad40884633.tar.gz bcm5719-llvm-1596c4531b3950f4c883013cb51182ad40884633.zip | |
N3189 Observers for the three handler functions
llvm-svn: 120712
| -rw-r--r-- | libcxx/include/exception | 4 | ||||
| -rw-r--r-- | libcxx/include/future | 4 | ||||
| -rw-r--r-- | libcxx/include/new | 2 | ||||
| -rw-r--r-- | libcxx/src/exception.cpp | 20 | ||||
| -rw-r--r-- | libcxx/src/new.cpp | 10 | ||||
| -rw-r--r-- | libcxx/test/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp | 39 | ||||
| -rw-r--r-- | libcxx/test/language.support/support.dynamic/alloc.errors/set.new.handler/get_new_handler.pass.cpp | 25 | ||||
| -rw-r--r-- | libcxx/test/language.support/support.exception/exception.terminate/set.terminate/get_terminate.pass.cpp | 25 |
8 files changed, 120 insertions, 9 deletions
diff --git a/libcxx/include/exception b/libcxx/include/exception index 845697203be..4871f41394a 100644 --- a/libcxx/include/exception +++ b/libcxx/include/exception @@ -40,10 +40,12 @@ public: typedef void (*unexpected_handler)(); unexpected_handler set_unexpected(unexpected_handler f ) throw(); +unexpected_handler get_unexpected() throw(); void unexpected [[noreturn]] (); typedef void (*terminate_handler)(); terminate_handler set_terminate(terminate_handler f ) throw(); +terminate_handler get_terminate() throw(); void terminate [[noreturn]] (); bool uncaught_exception() throw(); @@ -102,10 +104,12 @@ public: typedef void (*unexpected_handler)(); _LIBCPP_VISIBLE unexpected_handler set_unexpected(unexpected_handler) throw(); +_LIBCPP_VISIBLE unexpected_handler get_unexpected() throw(); _LIBCPP_VISIBLE void unexpected(); typedef void (*terminate_handler)(); _LIBCPP_VISIBLE terminate_handler set_terminate(terminate_handler) throw(); +_LIBCPP_VISIBLE terminate_handler get_terminate() throw(); _LIBCPP_VISIBLE void terminate() __attribute__((__noreturn__)); _LIBCPP_VISIBLE bool uncaught_exception() throw(); diff --git a/libcxx/include/future b/libcxx/include/future index 73a6391e0ec..3be5f0520a7 100644 --- a/libcxx/include/future +++ b/libcxx/include/future @@ -2297,6 +2297,8 @@ future<_R&>::share() return shared_future<_R&>(_STD::move(*this)); } +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + inline _LIBCPP_INLINE_VISIBILITY shared_future<void> future<void>::share() @@ -2304,6 +2306,8 @@ future<void>::share() return shared_future<void>(_STD::move(*this)); } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_FUTURE diff --git a/libcxx/include/new b/libcxx/include/new index 4b3c4b877c6..68f0274b9c4 100644 --- a/libcxx/include/new +++ b/libcxx/include/new @@ -32,6 +32,7 @@ struct nothrow_t {}; extern const nothrow_t nothrow; typedef void (*new_handler)(); new_handler set_new_handler(new_handler new_p) throw(); +new_handler get_new_handler() throw(); } // std @@ -85,6 +86,7 @@ struct _LIBCPP_VISIBLE nothrow_t {}; extern _LIBCPP_VISIBLE const nothrow_t nothrow; typedef void (*new_handler)(); _LIBCPP_VISIBLE new_handler set_new_handler(new_handler) throw(); +_LIBCPP_VISIBLE new_handler get_new_handler() throw(); } // std diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp index 1ab5a19520c..062114c251f 100644 --- a/libcxx/src/exception.cpp +++ b/libcxx/src/exception.cpp @@ -26,9 +26,13 @@ std::unexpected_handler std::set_unexpected(std::unexpected_handler func) throw() { - std::terminate_handler old = __unexpected_handler; - __unexpected_handler = func; - return old; + return __sync_lock_test_and_set(&__unexpected_handler, func); +} + +std::unexpected_handler +std::get_unexpected() throw() +{ + return __sync_fetch_and_add(&__unexpected_handler, (std::unexpected_handler)0); } void @@ -42,9 +46,13 @@ std::unexpected() std::terminate_handler std::set_terminate(std::terminate_handler func) throw() { - std::terminate_handler old = __terminate_handler; - __terminate_handler = func; - return old; + return __sync_lock_test_and_set(&__terminate_handler, func); +} + +std::terminate_handler +std::get_terminate() throw() +{ + return __sync_fetch_and_add(&__terminate_handler, (std::terminate_handler)0); } void diff --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp index 874ad6c0230..a3783d47efa 100644 --- a/libcxx/src/new.cpp +++ b/libcxx/src/new.cpp @@ -130,9 +130,13 @@ const nothrow_t nothrow = {}; new_handler set_new_handler(new_handler handler) throw() { - new_handler r = __new_handler; - __new_handler = handler; - return r; + return __sync_lock_test_and_set(&__new_handler, handler); +} + +new_handler +get_new_handler() throw() +{ + return __sync_fetch_and_add(&__new_handler, (new_handler)0); } bad_alloc::bad_alloc() throw() diff --git a/libcxx/test/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp b/libcxx/test/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp new file mode 100644 index 00000000000..8b0a0b979de --- /dev/null +++ b/libcxx/test/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// test get_unexpected + +#include <exception> +#include <cassert> +#include <cstdlib> + +void f1() {} +void f2() {} + +void f3() +{ + std::exit(0); +} + +int main() +{ + + std::unexpected_handler old = std::get_unexpected(); + // verify there is a previous unexpected handler + assert(old); + std::set_unexpected(f1); + assert(std::get_unexpected() == f1); + // verify f1 was replace with f2 + std::set_unexpected(f2); + assert(std::get_unexpected() == f2); + // verify calling original unexpected handler calls terminate + std::set_terminate(f3); + (*old)(); + assert(0); +} diff --git a/libcxx/test/language.support/support.dynamic/alloc.errors/set.new.handler/get_new_handler.pass.cpp b/libcxx/test/language.support/support.dynamic/alloc.errors/set.new.handler/get_new_handler.pass.cpp new file mode 100644 index 00000000000..55a3edabfed --- /dev/null +++ b/libcxx/test/language.support/support.dynamic/alloc.errors/set.new.handler/get_new_handler.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// test get_new_handler + +#include <new> +#include <cassert> + +void f1() {} +void f2() {} + +int main() +{ + assert(std::get_new_handler() == 0); + std::set_new_handler(f1); + assert(std::get_new_handler() == f1); + std::set_new_handler(f2); + assert(std::get_new_handler() == f2); +} diff --git a/libcxx/test/language.support/support.exception/exception.terminate/set.terminate/get_terminate.pass.cpp b/libcxx/test/language.support/support.exception/exception.terminate/set.terminate/get_terminate.pass.cpp new file mode 100644 index 00000000000..82ae4aaa88d --- /dev/null +++ b/libcxx/test/language.support/support.exception/exception.terminate/set.terminate/get_terminate.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// test get_terminate + +#include <exception> +#include <cstdlib> +#include <cassert> + +void f1() {} +void f2() {} + +int main() +{ + std::set_terminate(f1); + assert(std::get_terminate() == f1); + std::set_terminate(f2); + assert(std::get_terminate() == f2); +} |

