https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103993
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Last reconfirmed| |2025-09-30
Ever confirmed|0 |1
Status|UNCONFIRMED |NEW
--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This seems like another case that triggers in the libstdc++ testsuite, for
23_containers/map/modifiers/insert/92300.cc
Similar to comment 4, this is a throwing new, and if I remove the check for oom
and the throw, there's no warning:
#include <map>
#include <memory>
#include <cstdlib>
bool oom = false;
void* operator new(std::size_t n)
{
if (oom)
throw std::bad_alloc();
return std::malloc(n);
}
void operator delete(void* p) noexcept
{
std::free(p);
}
void operator delete(void* p, std::size_t) noexcept
{
std::free(p);
}
int main()
{
std::map<int, int> m;
(void) m[0];
}
In function 'void operator delete(void*, std::size_t)',
inlined from 'void std::__new_allocator<_Tp>::deallocate(_Tp*, size_type)
[with _Tp = std::_Rb_tree_node<std::pair<const int, int> >]' at
/home/jwakely/gcc/16/include/c++/16.0.0/bits/new_allocator.h:172:59,
inlined from 'static void std::allocator_traits<std::allocator<_Tp1>
>::deallocate(allocator_type&, pointer, size_type) [with _Tp =
std::_Rb_tree_node<std::pair<const int, int> >]' at
/home/jwakely/gcc/16/include/c++/16.0.0/bits/alloc_traits.h:649:23,
inlined from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_M_put_node(_Node_ptr) [with _Key = int; _Val = std::pair<const int,
int>; _KeyOfValue = std::_Select1st<std::pair<const int, int> >; _Compare =
std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >]' at
/home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_tree.h:1191:32,
inlined from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_M_drop_node(_Node_ptr) [with _Key = int; _Val = std::pair<const int,
int>; _KeyOfValue = std::_Select1st<std::pair<const int, int> >; _Compare =
std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >]' at
/home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_tree.h:1274:13,
inlined from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_Auto_node::~_Auto_node() [with _Key = int; _Val = std::pair<const
int, int>; _KeyOfValue = std::_Select1st<std::pair<const int, int> >; _Compare
= std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >]' at
/home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_tree.h:2292:23,
inlined from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_M_emplace_hint_unique(const_iterator, _Args&& ...) [with _Args =
{const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Key =
int; _Val = std::pair<const int, int>; _KeyOfValue =
std::_Select1st<std::pair<const int, int> >; _Compare = std::less<int>; _Alloc
= std::allocator<std::pair<const int, int> >]' at
/home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_tree.h:3089:7,
inlined from 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type&
std::map<_Key, _Tp, _Compare, _Alloc>::operator[](key_type&&) [with _Key = int;
_Tp = int; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const
int, int> >]' at /home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_map.h:555:37,
inlined from 'int main()' at newdel.cc:27:13:
newdel.cc:21:12: warning: 'void free(void*)' called on pointer returned from a
mismatched allocation function [-Wmismatched-new-delete]
21 | std::free(p);
| ~~~~~~~~~^~~
In file included from
/home/jwakely/gcc/16/include/c++/16.0.0/x86_64-pc-linux-gnu/bits/c++allocator.h:33,
from
/home/jwakely/gcc/16/include/c++/16.0.0/bits/allocator.h:46,
from
/home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_tree.h:66,
from /home/jwakely/gcc/16/include/c++/16.0.0/map:64,
from newdel.cc:1:
In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const
void*) [with _Tp = std::_Rb_tree_node<std::pair<const int, int> >]',
inlined from 'static _Tp* std::allocator_traits<std::allocator<_Tp1>
>::allocate(allocator_type&, size_type) [with _Tp =
std::_Rb_tree_node<std::pair<const int, int> >]' at
/home/jwakely/gcc/16/include/c++/16.0.0/bits/alloc_traits.h:614:28,
inlined from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_Node_ptr std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_M_get_node() [with _Key = int; _Val = std::pair<const int, int>;
_KeyOfValue = std::_Select1st<std::pair<const int, int> >; _Compare =
std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >]' at
/home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_tree.h:1170:37,
inlined from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_Node_ptr std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_M_create_node(_Args&& ...) [with _Args = {const
std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Key = int; _Val
= std::pair<const int, int>; _KeyOfValue = std::_Select1st<std::pair<const int,
int> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int,
int> >]' at /home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_tree.h:1253:33,
inlined from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_Auto_node::_Auto_node(std::_Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>&, _Args&& ...) [with _Args = {const
std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Key = int; _Val
= std::pair<const int, int>; _KeyOfValue = std::_Select1st<std::pair<const int,
int> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int,
int> >]' at /home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_tree.h:2286:32,
inlined from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_M_emplace_hint_unique(const_iterator, _Args&& ...) [with _Args =
{const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Key =
int; _Val = std::pair<const int, int>; _KeyOfValue =
std::_Select1st<std::pair<const int, int> >; _Compare = std::less<int>; _Alloc
= std::allocator<std::pair<const int, int> >]' at
/home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_tree.h:3084:13,
inlined from 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type&
std::map<_Key, _Tp, _Compare, _Alloc>::operator[](key_type&&) [with _Key = int;
_Tp = int; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const
int, int> >]' at /home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_map.h:555:37,
inlined from 'int main()' at newdel.cc:27:13:
/home/jwakely/gcc/16/include/c++/16.0.0/bits/new_allocator.h:151:73: note:
returned from 'void* operator new(std::size_t)'
151 | return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n *
sizeof(_Tp)));
|
^
This is just annoying, because there's no mismatch at all. We get memory from
operator new and release it with a matching operator delete. The fact that new
is implemented using malloc and delete is implemented using free should be
irrelevant.
Adding [[gnu::noinline]] to the operator delete overloads prevents the warning,
because now the compiler doesn't look inside operator delete to see that it's
implemented in terms of free.