PR libstdc++/85812 fix memory leak in std::make_exception_ptr
authorJonathan Wakely <jwakely@redhat.com>
Thu, 17 May 2018 15:03:29 +0000 (16:03 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 17 May 2018 15:03:29 +0000 (16:03 +0100)
PR libstdc++/85812
* libsupc++/cxxabi_init_exception.h (__cxa_free_exception): Declare.
* libsupc++/exception_ptr.h (make_exception_ptr) [__cpp_exceptions]:
Refactor to separate non-throwing and throwing implementations.
[__cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI]: Deallocate the memory
if constructing the object throws.

From-SVN: r260323

libstdc++-v3/ChangeLog
libstdc++-v3/libsupc++/cxxabi_init_exception.h
libstdc++-v3/libsupc++/exception_ptr.h

index 8359f4f5335ffa868e45b1f7b5cb22b322e77090..142f7c8317f980e5a249f5a1c43ff998d70c6ca8 100644 (file)
@@ -1,3 +1,12 @@
+2018-05-17  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/85812
+       * libsupc++/cxxabi_init_exception.h (__cxa_free_exception): Declare.
+       * libsupc++/exception_ptr.h (make_exception_ptr) [__cpp_exceptions]:
+       Refactor to separate non-throwing and throwing implementations.
+       [__cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI]: Deallocate the memory
+       if constructing the object throws.
+
 2018-05-15  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/85749
index d973a087f14ead47d185b6b84607cf1beef4e492..e438c1008d9b0bc2b7fad66eecea19e4fe0aade3 100644 (file)
@@ -62,6 +62,9 @@ namespace __cxxabiv1
       void*
       __cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW;
 
+      void
+      __cxa_free_exception(void*) _GLIBCXX_NOTHROW;
+
       // Initialize exception (this is a GNU extension)
       __cxa_refcounted_exception*
       __cxa_init_primary_exception(void *object, std::type_info *tinfo,
index a927327214ddc1553a0fdeda6641ca7b8d6505f2..bd355ed880bdbdcc7c504f137f8a8139519ad0d0 100644 (file)
@@ -178,25 +178,31 @@ namespace std
     exception_ptr 
     make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT
     {
-#if __cpp_exceptions
+#if __cpp_exceptions && __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI
+      void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex));
+      (void) __cxxabiv1::__cxa_init_primary_exception(
+         __e, const_cast<std::type_info*>(&typeid(__ex)),
+         __exception_ptr::__dest_thunk<_Ex>);
       try
        {
-#if __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI
-          void *__e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex));
-          (void)__cxxabiv1::__cxa_init_primary_exception(
-             __e, const_cast<std::type_info*>(&typeid(__ex)),
-             __exception_ptr::__dest_thunk<_Ex>);
           ::new (__e) _Ex(__ex);
           return exception_ptr(__e);
-#else
+       }
+      catch(...)
+       {
+         __cxxabiv1::__cxa_free_exception(__e);
+         return current_exception();
+       }
+#elif __cpp_exceptions
+      try
+       {
           throw __ex;
-#endif
        }
       catch(...)
        {
          return current_exception();
        }
-#else
+#else // no RTTI and no exceptions
       return exception_ptr();
 #endif
     }