https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63840
Bug ID: 63840 Summary: std::function copy constructor deletes an uninitialized pointer if new fails Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: tavianator at gmail dot com Created attachment 33953 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33953&action=edit Reproducer std::function's copy constructor looks like this: template<typename _Res, typename... _ArgTypes> function<_Res(_ArgTypes...)>:: function(const function& __x) : _Function_base() { if (static_cast<bool>(__x)) { _M_invoker = __x._M_invoker; _M_manager = __x._M_manager; __x._M_manager(_M_functor, __x._M_functor, __clone_functor); } } _M_manager(..., __clone_functor) calls _M_clone, which looks like this when the functor is stored on the heap: static void _M_clone(_Any_data& __dest, const _Any_data& __source, false_type) { __dest._M_access<_Functor*>() = new _Functor(*__source._M_access<_Functor*>()); } If operator new or the copy-constructor throws, __dest._M_pod_data remains uninitialized. Then the stack unwinds, and ~_Function_base() gets called: ~_Function_base() { if (_M_manager) _M_manager(_M_functor, _M_functor, __destroy_functor); } Which ultimately calls static void _M_destroy(_Any_data& __victim, false_type) { delete __victim._M_access<_Functor*>(); } Which deletes _M_pod_data. A simple fix could be: template<typename _Res, typename... _ArgTypes> function<_Res(_ArgTypes...)>:: function(const function& __x) : _Function_base() { if (static_cast<bool>(__x)) { + __x._M_manager(_M_functor, __x._M_functor, __clone_functor); _M_invoker = __x._M_invoker; _M_manager = __x._M_manager; - __x._M_manager(_M_functor, __x._M_functor, __clone_functor); } } I have a test case attached.