https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123513
Bug ID: 123513
Summary: False positive -Wmismatched-new-delete with a
non-member template operator new
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: aaron.puchert at sap dot com
Target Milestone: ---
Compile this with -Wall:
#include <cstddef>
#include <stdio.h>
#include <new>
template <size_t SlabSize>
class BumpAllocator {};
class C {};
template <size_t SlabSize>
void* operator new(size_t, BumpAllocator<SlabSize>&);
template <size_t SlabSize>
void operator delete(void*, BumpAllocator<SlabSize>&);
void test() {
BumpAllocator<1024> alloc;
new (alloc) C();
}
This warns:
<source>: In function 'void test()':
<source>:18:19: warning: 'void operator delete(void*, BumpAllocator<SlabSize>&)
[with long unsigned int SlabSize = 1024]' called on pointer returned from a
mismatched allocation function [-Wmismatched-new-delete]
18 | new (alloc) C();
| ^
<source>:18:19: note: returned from 'void* operator new(size_t,
BumpAllocator<SlabSize>&) [with long unsigned int SlabSize = 1024]'
18 | new (alloc) C();
| ^
This is reproducible with trunk, but I've debugged it with GCC 13. We're here:
valid_new_delete_pair_p (new_asm=new_asm@entry=0x7ffff6a74d00,
delete_asm=delete_asm@entry=0x7ffff6a74cc0,
pcertain=pcertain@entry=0x7fffffffd627)
at ../../gcc/tree.cc:14816
Source:
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/tree.cc;hb=releases/gcc-13.2.0#l14811.
(gdb) p new_name
$3 = 0x7ffff6a7c708 "_ZnwILm1024EEPvmR13BumpAllocatorIXT_EE"
(gdb) p delete_name
$4 = 0x7ffff6a4bca8 "_ZdlILm1024EEvPvR13BumpAllocatorIXT_EE"
We pass these lines:
14852 /* The following failures are certain mismatches. */
14853 *pcertain = true;
Then exit here after consuming "_Znw":
14859 /* 'j', 'm' and 'y' correspond to size_t. */
14860 if (new_name[3] != 'j' && new_name[3] != 'm' && new_name[3] != 'y')
14861 return false;
Before the desired "m" we have "ILm1024EEPv". "I[…]E" stands for a template
argument, "Lm1024E" stands for 1024, and "Pv" for the return type "void*".
It seems like the detection should skip template arguments (and if they exist,
the return type) before continuing with the parameters.