test the typeid of the exception before it is potentially moved
authorEric Niebler <eniebler@fb.com>
Thu, 4 May 2017 02:12:10 +0000 (19:12 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Thu, 4 May 2017 02:26:30 +0000 (19:26 -0700)
Summary: Access the RTTI of the incomming exception before it is potentially moved from when testing for slicing

Reviewed By: yfeldblum

Differential Revision: D4999189

fbshipit-source-id: 3e6c0a9f10a27810484330e9b37a5b0ec450ff88

folly/ExceptionWrapper-inl.h

index d5ad700..99cbd9d 100644 (file)
@@ -287,6 +287,16 @@ inline exception_wrapper::exception_wrapper(std::exception_ptr ptr, Ex& ex)
   assert(eptr_.ptr_);
 }
 
+namespace exception_wrapper_detail {
+template <class Ex>
+Ex&& dont_slice(Ex&& ex) {
+  assert(typeid(ex) == typeid(_t<std::decay<Ex>>) ||
+       !"Dynamic and static exception types don't match. Exception would "
+        "be sliced when storing in exception_wrapper.");
+  return std::forward<Ex>(ex);
+}
+}
+
 template <
     class Ex,
     class Ex_,
@@ -295,11 +305,9 @@ template <
             exception_wrapper::IsStdException<Ex_>,
             exception_wrapper::IsRegularExceptionType<Ex_>>::value)>
 inline exception_wrapper::exception_wrapper(Ex&& ex)
-    : exception_wrapper{std::forward<Ex>(ex), PlacementOf<Ex_>{}} {
-  // Don't slice!!!
-  assert(typeid(ex) == typeid(Ex_) ||
-       !"Dynamic and static exception types don't match. Exception would "
-        "be sliced when storing in exception_wrapper.");
+    : exception_wrapper{
+        exception_wrapper_detail::dont_slice(std::forward<Ex>(ex)),
+        PlacementOf<Ex_>{}} {
 }
 
 template <
@@ -308,11 +316,9 @@ template <
     FOLLY_REQUIRES_DEF(
         exception_wrapper::IsRegularExceptionType<Ex_>::value)>
 inline exception_wrapper::exception_wrapper(in_place_t, Ex&& ex)
-    : exception_wrapper{std::forward<Ex>(ex), PlacementOf<Ex_>{}} {
-  // Don't slice!!!
-  assert(typeid(ex) == typeid(Ex_) ||
-       !"Dynamic and static exception types don't match. Exception would "
-        "be sliced when storing in exception_wrapper.");
+    : exception_wrapper{
+        exception_wrapper_detail::dont_slice(std::forward<Ex>(ex)),
+        PlacementOf<Ex_>{}} {
 }
 
 inline void exception_wrapper::swap(exception_wrapper& that) noexcept {