https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125913
Bug ID: 125913
Summary: [16/17 regression] False positive
-Wfree-nonheap-object
Product: gcc
Version: 16.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: aleksandr9809 at gmail dot com
Target Milestone: ---
Hi,
While migrating private codebase to the GCC 16, I faced with the possibly
false-positive bug.
The minimized code with the our problem:
```cxx
// g++ -std=c++17 -O2 -Wall -Werror -c file.cpp
#include <atomic>
struct Interface {
virtual ~Interface() = default;
virtual void Release() = 0;
};
// Core of Implementation: delete this + ~dtor calls helper->Release()
struct Implementation : virtual Interface {
struct Helper {
int selfRc = 1;
std::atomic<int> ownerRc{1};
void Release() { if (--selfRc == 0) delete this; }
};
Helper* helper;
Implementation() : helper(new Helper) {}
virtual ~Implementation() { helper->Release(); }
void Release() override {
if (helper->ownerRc.fetch_sub(1) == 1)
delete this;
}
};
template<class T>
struct RAII {
T* p;
explicit RAII(T* p) : p(p) {}
virtual ~RAII() { p->Release(); }
};
struct OtherBase { virtual ~OtherBase() = default; };
// virtual MI => Implementation is at a non-zero offset from new()
struct Object final : virtual OtherBase, virtual Implementation {};
int main() {
RAII<Object> obj(new Object);
}
```
The compiler generates the next error message:
```
In destructor 'virtual Implementation::~Implementation()',
inlined from 'virtual void Implementation::Release()' at <source>:22:20,
inlined from 'virtual void Implementation::Release()' at <source>:20:10,
inlined from 'RAII<T>::~RAII() [with T = Object]' at <source>:30:33,
inlined from 'int main()' at <source>:40:1:
<source>:19:52: error: 'void operator delete(void*)' called on pointer
'<unknown>' with nonzero offset 8 [-Werror=free-nonheap-object]
19 | virtual ~Implementation() { helper->Release(); }
| ^
<source>: In function 'int main()':
<source>:39:26: note: returned from 'void* operator new(std::size_t)'
39 | RAII<Object> obj(new Object);
| ^~~~~~
```
The godbolt link with proof: https://www.godbolt.org/z/cG5xzGKc1
The issue is reproduced in both gcc trunk and gcc 16.1, but not on gcc 15.2
(Godbolt-provided) or earlier GCC versions (Debian-provided GCC 8.3.0, 10.2.1,
12.2.0, 14.2.0).
Maybe it's the C++ standard misunderstanding, but there's no triggers from ASan
or UBSan from the gcc 16.1.0 (godbolt-provided).
Best regards,
Alex