rmaprath updated this revision to Diff 42694.
rmaprath added a comment.

Simplified the changes to `__config` header.


http://reviews.llvm.org/D14653

Files:
  include/__config
  include/array
  test/std/containers/sequences/array/at.pass.cpp
  test/support/noexcept.h

Index: test/support/noexcept.h
===================================================================
--- /dev/null
+++ test/support/noexcept.h
@@ -0,0 +1,53 @@
+// -*- C++ -*-
+//===----------------------------- noexcept.h -----------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+#ifndef NOEXCEPT_H
+#define NOEXCEPT_H
+
+#ifdef _LIBCPP_NO_EXCEPTIONS
+
+#include <setjmp.h>
+#include <cstdio>
+#include "test_macros.h"
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+# if TEST_STD_VER >= 11
+#   define TLS_SPEC thread_local
+# elif defined(_LIBCPP_MSVC)
+#   define TLS_SPEC __declspec(thread)
+# else
+#   define TLS_SPEC __thread
+# endif
+#else
+# define TLS_SPEC
+#endif
+
+// Some tests launch multiple threads, in which case we need to make sure that
+// try_buf is maintained per-thread, otherwise setjmp()/longjmp() will attempt
+// to jump between threads!
+TLS_SPEC jmp_buf try_buf;
+#undef TLS_SPEC
+
+// Re-write try/catch with if/else to mimic a similar control flow when testing
+// the no-exceptions library variant. The idea is to save as much of the usual
+// with-exceptions assertions as possible. This of course does not work when
+// there are multiple catch statements, in those cases we have to use the
+// _LIBCPP_NO_EXCEPTIONS macro as appropriate; such cases are rare.
+#define try if(!setjmp(try_buf))
+#define catch(ex) else
+
+// Jump back to the catch (now else) clause.
+void __libcxx_noexceptions_abort(const char *msg) {
+  fprintf(stderr, "%s\n", msg);
+  longjmp(try_buf, 1);
+}
+
+#endif // _LIBCPP_NO_EXCEPTIONS
+
+#endif // NOEXCEPT_H
Index: test/std/containers/sequences/array/at.pass.cpp
===================================================================
--- test/std/containers/sequences/array/at.pass.cpp
+++ test/std/containers/sequences/array/at.pass.cpp
@@ -7,7 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// XFAIL: libcpp-no-exceptions
 // <array>
 
 // reference operator[] (size_type)
@@ -19,6 +18,7 @@
 #include <cassert>
 
 #include "test_macros.h"
+#include "noexcept.h"
 
 // std::array is explicitly allowed to be initialized with A a = { init-list };.
 // Disable the missing braces warning for this reason.
Index: include/array
===================================================================
--- include/array
+++ include/array
@@ -201,11 +201,7 @@
 array<_Tp, _Size>::at(size_type __n)
 {
     if (__n >= _Size)
-#ifndef _LIBCPP_NO_EXCEPTIONS
-        throw out_of_range("array::at");
-#else
-        assert(!"array::at out_of_range");
-#endif
+        _LIBCPP_THROW(out_of_range("array::at out_of_range"));
     return __elems_[__n];
 }
 
@@ -215,11 +211,7 @@
 array<_Tp, _Size>::at(size_type __n) const
 {
     if (__n >= _Size)
-#ifndef _LIBCPP_NO_EXCEPTIONS
-        throw out_of_range("array::at");
-#else
-        assert(!"array::at out_of_range");
-#endif
+        _LIBCPP_THROW(out_of_range("array::at out_of_range"));
     return __elems_[__n];
 }
 
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -281,7 +281,7 @@
 typedef __char32_t char32_t;
 #endif
 
-#if !(__has_feature(cxx_exceptions))
+#if !(__has_feature(cxx_exceptions)) && !defined(_LIBCPP_NO_EXCEPTIONS)
 #define _LIBCPP_NO_EXCEPTIONS
 #endif
 
@@ -825,6 +825,30 @@
 #define _LIBCPP_HAS_NO_ATOMIC_HEADER
 #endif
 
+#ifdef _LIBCPP_NO_EXCEPTIONS
+_LIBCPP_NORETURN _LIBCPP_WEAK void __libcxx_noexceptions_abort(const char *msg);
+extern "C++" {
+template<typename T>
+_LIBCPP_NORETURN _LIBCPP_ALWAYS_INLINE
+void __libcxx_noexceptions_report(T t, const char *msg = nullptr)
+{
+    if (__libcxx_noexceptions_abort) {
+      if (msg)
+        __libcxx_noexceptions_abort(msg);
+      else if (t.what())
+        __libcxx_noexceptions_abort(t.what());
+      else
+        __libcxx_noexceptions_abort("Exception raised, cannot propagate.\n");
+    }
+}
+}
+#define _LIBCPP_THROW(E) __libcxx_noexceptions_report(E)
+#define _LIBCPP_THROW_MSG(E, MSG) __libcxx_noexceptions_report(E, MSG)
+#else  // !_LIBCPP_NO_EXCEPTIONS
+#define _LIBCPP_THROW(E) throw E
+#define _LIBCPP_THROW_MSG(E, MSG) throw E
+#endif // _LIBCPP_NO_EXCEPTIONS
+
 #endif // __cplusplus
 
 #endif // _LIBCPP_CONFIG
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to