Implement LWG2784, and mark 2786, 2795, 2804, 2812, 2826, 2834, 2837 and 2838 as complete - since we do them already

llvm-svn: 297752
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 55cfe4c16beba63d5cd5647da6349fbb886ece08
diff --git a/include/exception b/include/exception
index 8828709..216ae0c 100644
--- a/include/exception
+++ b/include/exception
@@ -248,12 +248,17 @@
 #endif
 }
 
+template <class _From, class _To>
+struct __can_dynamic_cast : public _LIBCPP_BOOL_CONSTANT(
+              is_polymorphic<_From>::value &&
+                 (!is_base_of<_To, _From>::value ||
+                   is_convertible<const _From*, const _To*>::value)) {};
+
 template <class _Ep>
 inline _LIBCPP_INLINE_VISIBILITY
 void
-rethrow_if_nested(const _Ep& __e, typename enable_if<
-                                   is_polymorphic<_Ep>::value
-                                                   >::type* = 0)
+rethrow_if_nested(const _Ep& __e,
+                  typename enable_if< __can_dynamic_cast<_Ep, nested_exception>::value>::type* = 0)
 {
     const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e));
     if (__nep)
@@ -263,9 +268,8 @@
 template <class _Ep>
 inline _LIBCPP_INLINE_VISIBILITY
 void
-rethrow_if_nested(const _Ep&, typename enable_if<
-                                   !is_polymorphic<_Ep>::value
-                                                   >::type* = 0)
+rethrow_if_nested(const _Ep&,
+                  typename enable_if<!__can_dynamic_cast<_Ep, nested_exception>::value>::type* = 0)
 {
 }