[libcxx] r302393 - [libc++] Implement exception_ptr on Windows

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Sun May 7 18:17:50 PDT 2017


Author: ericwf
Date: Sun May  7 20:17:50 2017
New Revision: 302393

URL: http://llvm.org/viewvc/llvm-project?rev=302393&view=rev
Log:
[libc++] Implement exception_ptr on Windows

Summary:
This patch implements exception_ptr on Windows using the `__ExceptionPtrFoo` functions provided by MSVC.

The `__ExceptionPtrFoo` functions are defined inside the C++ standard library, `msvcprt`, which is unfortunate because it requires libc++ to link to the MSVC STL. However this doesn't seem to cause any immediate problems. However to be safe I kept all usages within the libc++ dylib so that user programs wouldn't have to link to MSVCPRT as well.

Note there are still 2 outstanding exception_ptr/nested_exception test failures.

* `current_exception.pass.cpp` needs to be rewritten for the Windows exception_ptr semantics which copy the exception every time.
* `rethrow_if_nested.pass.cpp` need investigation. It hits a stack overflow, likely from recursion.

This patch also gets most of the `<future>` tests passing as well.

Reviewers: mclow.lists, compnerd, bcraig, rmaprath, majnemer, BillyONeal, STL_MSFT

Subscribers: mgorny, cfe-commits

Differential Revision: https://reviews.llvm.org/D32927

Added:
    libcxx/trunk/src/support/runtime/exception_pointer_msvc.ipp
Modified:
    libcxx/trunk/include/exception
    libcxx/trunk/lib/CMakeLists.txt
    libcxx/trunk/src/exception.cpp
    libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp
    libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
    libcxx/trunk/test/std/language.support/support.exception/except.nested/assign.pass.cpp
    libcxx/trunk/test/std/language.support/support.exception/except.nested/ctor_copy.pass.cpp
    libcxx/trunk/test/std/language.support/support.exception/except.nested/ctor_default.pass.cpp
    libcxx/trunk/test/std/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp
    libcxx/trunk/test/std/language.support/support.exception/except.nested/rethrow_nested.pass.cpp
    libcxx/trunk/test/std/language.support/support.exception/except.nested/throw_with_nested.pass.cpp
    libcxx/trunk/test/std/language.support/support.exception/propagation/current_exception.pass.cpp
    libcxx/trunk/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp
    libcxx/trunk/test/std/language.support/support.exception/propagation/make_exception_ptr.pass.cpp
    libcxx/trunk/test/std/language.support/support.exception/propagation/rethrow_exception.pass.cpp

Modified: libcxx/trunk/include/exception
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/exception?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/include/exception (original)
+++ libcxx/trunk/include/exception Sun May  7 20:17:50 2017
@@ -134,23 +134,26 @@ class _LIBCPP_TYPE_VIS exception_ptr;
 _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
 _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
 
+#ifndef _LIBCPP_ABI_MICROSOFT
+
 class _LIBCPP_TYPE_VIS exception_ptr
 {
     void* __ptr_;
 public:
     _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {}
     _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
+
     exception_ptr(const exception_ptr&) _NOEXCEPT;
     exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
     ~exception_ptr() _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_EXPLICIT
-        operator bool() const _NOEXCEPT {return __ptr_ != nullptr;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT
+    {return __ptr_ != nullptr;}
 
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
         {return __x.__ptr_ == __y.__ptr_;}
+
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
         {return !(__x == __y);}
@@ -178,6 +181,54 @@ make_exception_ptr(_Ep __e) _NOEXCEPT
 #endif
 }
 
+#else // _LIBCPP_ABI_MICROSOFT
+
+class _LIBCPP_TYPE_VIS exception_ptr
+{
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-private-field"
+#endif
+    void* __ptr1_;
+    void* __ptr2_;
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+public:
+    exception_ptr() _NOEXCEPT;
+    exception_ptr(nullptr_t) _NOEXCEPT;
+    exception_ptr(const exception_ptr& __other) _NOEXCEPT;
+    exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
+    exception_ptr& operator=(nullptr_t) _NOEXCEPT;
+    ~exception_ptr() _NOEXCEPT;
+    _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT;
+};
+
+_LIBCPP_FUNC_VIS
+bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT;
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
+    {return !(__x == __y);}
+
+_LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;
+
+_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void *__except, const void* __ptr);
+_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr p);
+
+// This is a built-in template function which automagically extracts the required
+// information.
+template <class _E> void *__GetExceptionInfo(_E);
+
+template<class _Ep>
+exception_ptr
+make_exception_ptr(_Ep __e) _NOEXCEPT
+{
+  return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e));
+}
+
+#endif // _LIBCPP_ABI_MICROSOFT
 // nested_exception
 
 class _LIBCPP_EXCEPTION_ABI nested_exception

Modified: libcxx/trunk/lib/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/lib/CMakeLists.txt?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/lib/CMakeLists.txt (original)
+++ libcxx/trunk/lib/CMakeLists.txt Sun May  7 20:17:50 2017
@@ -121,6 +121,7 @@ if (LIBCXX_TARGETING_MSVC)
   add_library_flags(ucrt${LIB_SUFFIX}) # Universal C runtime
   add_library_flags(vcruntime${LIB_SUFFIX}) # C++ runtime
   add_library_flags(msvcrt${LIB_SUFFIX}) # C runtime startup files
+  add_library_flags(msvcprt${LIB_SUFFIX}) # C++ standard library. Required for exception_ptr internals.
   # Required for standards-complaint wide character formatting functions
   # (e.g. `printfw`/`scanfw`)
   add_library_flags(iso_stdio_wide_specifiers)

Modified: libcxx/trunk/src/exception.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/exception.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/src/exception.cpp (original)
+++ libcxx/trunk/src/exception.cpp Sun May  7 20:17:50 2017
@@ -20,7 +20,7 @@
 
 #if defined(_LIBCPP_ABI_MICROSOFT)
 #include "support/runtime/exception_msvc.ipp"
-#include "support/runtime/exception_pointer_unimplemented.ipp"
+#include "support/runtime/exception_pointer_msvc.ipp"
 #elif defined(_LIBCPPABI_VERSION)
 #include "support/runtime/exception_libcxxabi.ipp"
 #include "support/runtime/exception_pointer_cxxabi.ipp"

Added: libcxx/trunk/src/support/runtime/exception_pointer_msvc.ipp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/support/runtime/exception_pointer_msvc.ipp?rev=302393&view=auto
==============================================================================
--- libcxx/trunk/src/support/runtime/exception_pointer_msvc.ipp (added)
+++ libcxx/trunk/src/support/runtime/exception_pointer_msvc.ipp Sun May  7 20:17:50 2017
@@ -0,0 +1,94 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+
+_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCreate(_Out_ void*);
+_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrDestroy(_Inout_ void*);
+_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCopy(_Out_ void*,
+                                                              _In_ const void*);
+_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL
+__ExceptionPtrAssign(_Inout_ void*, _In_ const void*);
+_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL
+__ExceptionPtrCompare(_In_ const void*, _In_ const void*);
+_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL
+__ExceptionPtrToBool(_In_ const void*);
+_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrSwap(_Inout_ void*,
+                                                              _Inout_ void*);
+_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL
+__ExceptionPtrCurrentException(_Out_ void*);
+[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL
+__ExceptionPtrRethrow(_In_ const void*);
+_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL
+__ExceptionPtrCopyException(_Inout_ void*, _In_ const void*, _In_ const void*);
+
+namespace std {
+
+exception_ptr::exception_ptr() _NOEXCEPT { __ExceptionPtrCreate(this); }
+exception_ptr::exception_ptr(nullptr_t) _NOEXCEPT { __ExceptionPtrCreate(this); }
+
+exception_ptr::exception_ptr(const exception_ptr& __other) _NOEXCEPT {
+  __ExceptionPtrCopy(this, &__other);
+}
+exception_ptr& exception_ptr::operator=(const exception_ptr& __other) _NOEXCEPT {
+  __ExceptionPtrAssign(this, &__other);
+  return *this;
+}
+
+exception_ptr& exception_ptr::operator=(nullptr_t) _NOEXCEPT {
+  exception_ptr dummy;
+  __ExceptionPtrAssign(this, &dummy);
+  return *this;
+}
+
+exception_ptr::~exception_ptr() _NOEXCEPT { __ExceptionPtrDestroy(this); }
+
+exception_ptr::operator bool() const _NOEXCEPT {
+  return __ExceptionPtrToBool(this);
+}
+
+bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
+  return __ExceptionPtrCompare(&__x, &__y);
+}
+
+
+void swap(exception_ptr& lhs, exception_ptr& rhs) _NOEXCEPT {
+  __ExceptionPtrSwap(&rhs, &lhs);
+}
+
+exception_ptr __copy_exception_ptr(void* __except, const void* __ptr) {
+  exception_ptr __ret = nullptr;
+  if (__ptr)
+    __ExceptionPtrCopyException(&__ret, __except, __ptr);
+  return __ret;
+}
+
+exception_ptr current_exception() _NOEXCEPT {
+  exception_ptr __ret;
+  __ExceptionPtrCurrentException(&__ret);
+  return __ret;
+}
+
+_LIBCPP_NORETURN
+void rethrow_exception(exception_ptr p) { __ExceptionPtrRethrow(&p); }
+
+nested_exception::nested_exception() _NOEXCEPT : __ptr_(current_exception()) {}
+
+nested_exception::~nested_exception() _NOEXCEPT {}
+
+_LIBCPP_NORETURN
+void nested_exception::rethrow_nested() const {
+  if (__ptr_ == nullptr)
+    terminate();
+  rethrow_exception(__ptr_);
+}
+
+} // namespace std

Modified: libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp Sun May  7 20:17:50 2017
@@ -6,10 +6,6 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
-
-// This test depends on std::exception_ptr which has not yet been implemented.
-// XFAIL: LIBCXX-WINDOWS-FIXME
 
 // UNSUPPORTED: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads

Modified: libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp Sun May  7 20:17:50 2017
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// This test depends on std::exception_ptr which has not yet been implemented.
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
 // UNSUPPORTED: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 // UNSUPPORTED: c++98, c++03

Modified: libcxx/trunk/test/std/language.support/support.exception/except.nested/assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.exception/except.nested/assign.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/std/language.support/support.exception/except.nested/assign.pass.cpp (original)
+++ libcxx/trunk/test/std/language.support/support.exception/except.nested/assign.pass.cpp Sun May  7 20:17:50 2017
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// exception_ptr has not been implemented on Windows
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
 // <exception>
 
 // class nested_exception;

Modified: libcxx/trunk/test/std/language.support/support.exception/except.nested/ctor_copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.exception/except.nested/ctor_copy.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/std/language.support/support.exception/except.nested/ctor_copy.pass.cpp (original)
+++ libcxx/trunk/test/std/language.support/support.exception/except.nested/ctor_copy.pass.cpp Sun May  7 20:17:50 2017
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// exception_ptr has not been implemented on Windows
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
 // <exception>
 
 // class nested_exception;

Modified: libcxx/trunk/test/std/language.support/support.exception/except.nested/ctor_default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.exception/except.nested/ctor_default.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/std/language.support/support.exception/except.nested/ctor_default.pass.cpp (original)
+++ libcxx/trunk/test/std/language.support/support.exception/except.nested/ctor_default.pass.cpp Sun May  7 20:17:50 2017
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// exception_ptr has not been implemented on Windows
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
 // <exception>
 
 // class nested_exception;

Modified: libcxx/trunk/test/std/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/std/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp (original)
+++ libcxx/trunk/test/std/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp Sun May  7 20:17:50 2017
@@ -7,10 +7,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-// exception_ptr has not been implemented on Windows
+// UNSUPPORTED: libcpp-no-exceptions
+
+// This test fails due to a stack overflow
 // XFAIL: LIBCXX-WINDOWS-FIXME
 
-// UNSUPPORTED: libcpp-no-exceptions
 // <exception>
 
 // class nested_exception;

Modified: libcxx/trunk/test/std/language.support/support.exception/except.nested/rethrow_nested.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.exception/except.nested/rethrow_nested.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/std/language.support/support.exception/except.nested/rethrow_nested.pass.cpp (original)
+++ libcxx/trunk/test/std/language.support/support.exception/except.nested/rethrow_nested.pass.cpp Sun May  7 20:17:50 2017
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// exception_ptr has not been implemented on Windows
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
 // UNSUPPORTED: libcpp-no-exceptions
 // <exception>
 

Modified: libcxx/trunk/test/std/language.support/support.exception/except.nested/throw_with_nested.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.exception/except.nested/throw_with_nested.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/std/language.support/support.exception/except.nested/throw_with_nested.pass.cpp (original)
+++ libcxx/trunk/test/std/language.support/support.exception/except.nested/throw_with_nested.pass.cpp Sun May  7 20:17:50 2017
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// exception_ptr has not been implemented on Windows
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
 // UNSUPPORTED: libcpp-no-exceptions
 // <exception>
 

Modified: libcxx/trunk/test/std/language.support/support.exception/propagation/current_exception.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.exception/propagation/current_exception.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/std/language.support/support.exception/propagation/current_exception.pass.cpp (original)
+++ libcxx/trunk/test/std/language.support/support.exception/propagation/current_exception.pass.cpp Sun May  7 20:17:50 2017
@@ -7,7 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-// exception_ptr has not been implemented on Windows
+// This test needs to be rewritten for the Windows exception_ptr semantics
+// which copy the exception each time the exception_ptr is copied.
 // XFAIL: LIBCXX-WINDOWS-FIXME
 
 // UNSUPPORTED: libcpp-no-exceptions

Modified: libcxx/trunk/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp (original)
+++ libcxx/trunk/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp Sun May  7 20:17:50 2017
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// exception_ptr has not been implemented on Windows
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
 // <exception>
 
 // typedef unspecified exception_ptr;

Modified: libcxx/trunk/test/std/language.support/support.exception/propagation/make_exception_ptr.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.exception/propagation/make_exception_ptr.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/std/language.support/support.exception/propagation/make_exception_ptr.pass.cpp (original)
+++ libcxx/trunk/test/std/language.support/support.exception/propagation/make_exception_ptr.pass.cpp Sun May  7 20:17:50 2017
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// exception_ptr has not been implemented on Windows
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
 // UNSUPPORTED: libcpp-no-exceptions
 // <exception>
 
@@ -41,7 +38,12 @@ int main()
         }
         catch (const A& a)
         {
+#ifndef _LIBCPP_ABI_MICROSOFT
             assert(A::constructed == 1);
+#else
+            // On Windows exception_ptr copies the exception
+            assert(A::constructed == 2);
+#endif
             assert(p != nullptr);
             p = nullptr;
             assert(p == nullptr);
@@ -50,4 +52,5 @@ int main()
         }
         assert(A::constructed == 0);
     }
+    assert(A::constructed == 0);
 }

Modified: libcxx/trunk/test/std/language.support/support.exception/propagation/rethrow_exception.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.exception/propagation/rethrow_exception.pass.cpp?rev=302393&r1=302392&r2=302393&view=diff
==============================================================================
--- libcxx/trunk/test/std/language.support/support.exception/propagation/rethrow_exception.pass.cpp (original)
+++ libcxx/trunk/test/std/language.support/support.exception/propagation/rethrow_exception.pass.cpp Sun May  7 20:17:50 2017
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// exception_ptr has not been implemented on Windows
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
 // UNSUPPORTED: libcpp-no-exceptions
 // <exception>
 
@@ -49,7 +46,12 @@ int main()
         }
         catch (const A& a)
         {
+#ifndef _LIBCPP_ABI_MICROSOFT
             assert(A::constructed == 1);
+#else
+            // On Windows the exception_ptr copies the exception
+            assert(A::constructed == 2);
+#endif
             assert(p != nullptr);
             p = nullptr;
             assert(p == nullptr);
@@ -58,4 +60,5 @@ int main()
         }
         assert(A::constructed == 0);
     }
+    assert(A::constructed == 0);
 }




More information about the cfe-commits mailing list