From 7a554be7a7620b69b5b9b87c583d70e606976326 Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Fri, 26 Nov 2021 15:50:16 -0600 Subject: [PATCH] GS: Fix compiler warning and possible memory leak on exception --- pcsx2/GS/GSAlignedClass.h | 6 ++++++ pcsx2/GS/GSRingHeap.h | 16 +++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/pcsx2/GS/GSAlignedClass.h b/pcsx2/GS/GSAlignedClass.h index 4fd1873e69..b2a71d8b77 100644 --- a/pcsx2/GS/GSAlignedClass.h +++ b/pcsx2/GS/GSAlignedClass.h @@ -38,6 +38,12 @@ public: return ptr; } + void operator delete(void* ptr, void* placement_ptr) + { + // Just here to satisfy compilers + // Person who calls in-place placement new must handle error case + } + void* operator new[](size_t size) { return _aligned_malloc(size, i); diff --git a/pcsx2/GS/GSRingHeap.h b/pcsx2/GS/GSRingHeap.h index c36524c5ac..90d177b134 100644 --- a/pcsx2/GS/GSRingHeap.h +++ b/pcsx2/GS/GSRingHeap.h @@ -64,18 +64,18 @@ public: template T* make(Args&&... args) { - void* ptr = alloc(sizeof(T), alignof(T)); - new (ptr) T(std::forward(args)...); - return static_cast(ptr); + std::unique_ptr ptr(alloc(sizeof(T), alignof(T)), GSRingHeap::free); + new (ptr.get()) T(std::forward(args)...); + return static_cast(ptr.release()); } /// Allocate and default-initialize `count` `T`s template T* make_array(size_t count) { - void* ptr = alloc(sizeof(T) * count, alignof(T)); - new (ptr) T[count](); - return static_cast(ptr); + std::unique_ptr ptr(alloc(sizeof(T) * count, alignof(T)), GSRingHeap::free); + new (ptr.get()) T[count](); + return static_cast(ptr.release()); } /// Free a pointer allocated with `alloc` @@ -207,17 +207,19 @@ public: SharedPtr make_shared(Args&&... args) { using Header = typename SharedPtr::AllocationHeader; - constexpr size_t alloc_size = sizeof(T) + sizeof(Header); + static constexpr size_t alloc_size = sizeof(T) + sizeof(Header); static_assert(alignof(Header) <= MIN_ALIGN, "Header alignment too high"); static_assert(alloc_size <= UINT32_MAX, "Allocation overflow"); void* ptr = alloc_internal(sizeof(T), getAlignMask(alignof(T)), sizeof(Header)); + std::unique_ptr guard(ptr, [](void* p){ free_internal(p, alloc_size); }); Header* header = static_cast(ptr); header->size = static_cast(alloc_size); header->refcnt.store(1, std::memory_order_relaxed); T* tptr = reinterpret_cast(header + 1); new (tptr) T(std::forward(args)...); + guard.release(); return SharedPtr(tptr); }