summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHoward Hinnant <hhinnant@apple.com>2010-12-02 16:45:21 +0000
committerHoward Hinnant <hhinnant@apple.com>2010-12-02 16:45:21 +0000
commit1596c4531b3950f4c883013cb51182ad40884633 (patch)
tree969833db70ead1f9cf8f6d0ec88590ab60858fbe
parentcdae9242fa11b0bb9a575dc4632fc3008c662339 (diff)
downloadbcm5719-llvm-1596c4531b3950f4c883013cb51182ad40884633.tar.gz
bcm5719-llvm-1596c4531b3950f4c883013cb51182ad40884633.zip
N3189 Observers for the three handler functions
llvm-svn: 120712
-rw-r--r--libcxx/include/exception4
-rw-r--r--libcxx/include/future4
-rw-r--r--libcxx/include/new2
-rw-r--r--libcxx/src/exception.cpp20
-rw-r--r--libcxx/src/new.cpp10
-rw-r--r--libcxx/test/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp39
-rw-r--r--libcxx/test/language.support/support.dynamic/alloc.errors/set.new.handler/get_new_handler.pass.cpp25
-rw-r--r--libcxx/test/language.support/support.exception/exception.terminate/set.terminate/get_terminate.pass.cpp25
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);
+}
OpenPOWER on IntegriCloud