Skip to content

Commit 957ddbb

Browse files
authored
Fix gcc warnings when building with optimizations. (#672)
* Fix gcc warnings when building with optimizations. When building the allocator_tutorial_pmr demo with -O2, gcc is throwing an error saying that new and delete are mismatched. This is something of a misnomer, however; the real problem is that the global new override we have in that demo is actually implemented incorrectly. In particular, the documentation at https://en.cppreference.com/w/cpp/memory/new/operator_new very clearly specifies that operator new either has to return a valid pointer, or throw an exception on error. Our version wasn't throwing the exception, so change it to throw std::bad_alloc if std::malloc fails. While we are in here, also fix another small possible is where std::malloc could return nullptr on a zero-sized object, thus throwing an exception it shouldn't. Signed-off-by: Chris Lalancette <[email protected]> * Always inline the new and delete operators. That's because gcc 13 has a bug where it can sometimes inline one or the other, and then it detects that they mismatch. For gcc and clang, just force them to always be inline in this demo. Signed-off-by: Chris Lalancette <[email protected]> * Switch to NOINLINE instead. Both clang and MSVC don't like inlining these, so instead ensure that they are *not* inlined. This also works because the problem is when new is inlined but not delete (or vice-versa). As long as they are both not inlined, this should fix the warning. Signed-off-by: Chris Lalancette <[email protected]>
1 parent 0f3071f commit 957ddbb

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

demo_nodes_cpp/src/topics/allocator_tutorial_pmr.cpp

+24-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <list>
1717
#include <memory>
1818
#include <memory_resource>
19+
#include <stdexcept>
1920
#include <string>
2021
#include <utility>
2122

@@ -64,15 +65,34 @@ static bool is_running = false;
6465
static uint32_t global_runtime_allocs = 0;
6566
static uint32_t global_runtime_deallocs = 0;
6667

67-
void * operator new(std::size_t size)
68+
// Due to GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103993, we
69+
// always inline the overridden new and delete operators.
70+
71+
#if defined(__GNUC__) || defined(__clang__)
72+
#define NOINLINE __attribute__((noinline))
73+
#else
74+
#define NOINLINE
75+
#endif
76+
77+
NOINLINE void * operator new(std::size_t size)
6878
{
79+
if (size == 0) {
80+
++size;
81+
}
82+
6983
if (is_running) {
7084
global_runtime_allocs++;
7185
}
72-
return std::malloc(size);
86+
87+
void * ptr = std::malloc(size);
88+
if (ptr != nullptr) {
89+
return ptr;
90+
}
91+
92+
throw std::bad_alloc{};
7393
}
7494

75-
void operator delete(void * ptr, size_t size) noexcept
95+
NOINLINE void operator delete(void * ptr, size_t size) noexcept
7696
{
7797
(void)size;
7898
if (ptr != nullptr) {
@@ -83,7 +103,7 @@ void operator delete(void * ptr, size_t size) noexcept
83103
}
84104
}
85105

86-
void operator delete(void * ptr) noexcept
106+
NOINLINE void operator delete(void * ptr) noexcept
87107
{
88108
if (ptr != nullptr) {
89109
if (is_running) {

0 commit comments

Comments
 (0)