[Bug libstdc++/63840] New: std::function copy constructor deletes an uninitialized pointer if new fails
tavianator at gmail dot com
gcc-bugzilla@gcc.gnu.org
Wed Nov 12 20:46:00 GMT 2014
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.
More information about the Gcc-bugs
mailing list