From 1cf2fd1c2b81010041080e5448c3ee43b452622f Mon Sep 17 00:00:00 2001
From: Guilherme Gonzaga <guilhermgonzaga@gmail.com>
Date: Mon, 14 Feb 2022 20:18:50 -0400
Subject: [PATCH 1/2] Mark unused parameters with [[gnu::unused]]

---
 cores/arduino/new.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/cores/arduino/new.cpp b/cores/arduino/new.cpp
index 7ca493169..2c05cd31f 100644
--- a/cores/arduino/new.cpp
+++ b/cores/arduino/new.cpp
@@ -56,7 +56,7 @@ void * operator new[](std::size_t size) {
   return operator new(size);
 }
 
-void * operator new(std::size_t size, const std::nothrow_t tag) noexcept {
+void * operator new(std::size_t size, [[gnu::unused]] const std::nothrow_t tag) noexcept {
 #if defined(NEW_TERMINATES_ON_FAILURE)
   // Cannot call throwing operator new as standard suggests, so call
   // new_helper directly then
@@ -65,7 +65,7 @@ void * operator new(std::size_t size, const std::nothrow_t tag) noexcept {
   return operator new(size);
 #endif
 }
-void * operator new[](std::size_t size, const std::nothrow_t& tag) noexcept {
+void * operator new[](std::size_t size, [[gnu::unused]] const std::nothrow_t& tag) noexcept {
 #if defined(NEW_TERMINATES_ON_FAILURE)
   // Cannot call throwing operator new[] as standard suggests, so call
   // malloc directly then
@@ -100,10 +100,10 @@ void operator delete[](void * ptr, std::size_t size) noexcept {
 }
 #endif // __cplusplus >= 201402L
 
-void operator delete(void* ptr, const std::nothrow_t& tag) noexcept {
+void operator delete(void* ptr, [[gnu::unused]] const std::nothrow_t& tag) noexcept {
   operator delete(ptr);
 }
-void operator delete[](void* ptr, const std::nothrow_t& tag) noexcept {
+void operator delete[](void* ptr, [[gnu::unused]] const std::nothrow_t& tag) noexcept {
   operator delete[](ptr);
 }
 

From c829e46729e7ece50909f262bf6c241d49ee1f29 Mon Sep 17 00:00:00 2001
From: Matthijs Kooijman <matthijs@stdin.nl>
Date: Tue, 21 Jun 2022 17:41:38 +0200
Subject: [PATCH 2/2] Move operator new weak attributes into cpp file

These were introduced in commit 4e469e0 (Allow overriding selected
operator new and delete functions) with the intention to make the
Arduino-provided definitions weak and allow them to be replaced by
sketch-provided or library-provided versions.

However, the attributes were placed in the `<new>` header file, causing
*all* implementations (that `#include <new>`) to become weak (including
sketch or library versions), which is not the intention.

This commit fixes this by moving the weak attributes into the cpp file,
causing only the Arduino-provided implementations to become weak.

Note that in practice, the linking order (or maybe the use of an archive
file for linking the core) seems to ensure that the sketch-provided
versions are preferred over the the Arduino-provided versions, so even
without this commit these operators can be replaced by the sketch.
---
 cores/arduino/new     | 20 ++++++++++----------
 cores/arduino/new.cpp | 20 ++++++++++----------
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/cores/arduino/new b/cores/arduino/new
index 8cf21038e..8f2fa0e43 100644
--- a/cores/arduino/new
+++ b/cores/arduino/new
@@ -39,25 +39,25 @@ namespace std {
   using size_t = ::size_t;
 } // namespace std
 
-[[gnu::weak]] void * operator new(std::size_t size);
-[[gnu::weak]] void * operator new[](std::size_t size);
+void * operator new(std::size_t size);
+void * operator new[](std::size_t size);
 
-[[gnu::weak]] void * operator new(std::size_t size, const std::nothrow_t tag) noexcept;
-[[gnu::weak]] void * operator new[](std::size_t size, const std::nothrow_t& tag) noexcept;
+void * operator new(std::size_t size, const std::nothrow_t tag) noexcept;
+void * operator new[](std::size_t size, const std::nothrow_t& tag) noexcept;
 
 void * operator new(std::size_t size, void *place) noexcept;
 void * operator new[](std::size_t size, void *place) noexcept;
 
-[[gnu::weak]] void operator delete(void * ptr) noexcept;
-[[gnu::weak]] void operator delete[](void * ptr) noexcept;
+void operator delete(void * ptr) noexcept;
+void operator delete[](void * ptr) noexcept;
 
 #if __cplusplus >= 201402L
-[[gnu::weak]] void operator delete(void* ptr, std::size_t size) noexcept;
-[[gnu::weak]] void operator delete[](void * ptr, std::size_t size) noexcept;
+void operator delete(void* ptr, std::size_t size) noexcept;
+void operator delete[](void * ptr, std::size_t size) noexcept;
 #endif // __cplusplus >= 201402L
 
-[[gnu::weak]] void operator delete(void* ptr, const std::nothrow_t& tag) noexcept;
-[[gnu::weak]] void operator delete[](void* ptr, const std::nothrow_t& tag) noexcept;
+void operator delete(void* ptr, const std::nothrow_t& tag) noexcept;
+void operator delete[](void* ptr, const std::nothrow_t& tag) noexcept;
 
 void operator delete(void* ptr, void* place) noexcept;
 void operator delete[](void* ptr, void* place) noexcept;
diff --git a/cores/arduino/new.cpp b/cores/arduino/new.cpp
index 2c05cd31f..c024d1d7f 100644
--- a/cores/arduino/new.cpp
+++ b/cores/arduino/new.cpp
@@ -44,7 +44,7 @@ static void * new_helper(std::size_t size) {
   return malloc(size);
 }
 
-void * operator new(std::size_t size) {
+[[gnu::weak]] void * operator new(std::size_t size) {
   void *res = new_helper(size);
 #if defined(NEW_TERMINATES_ON_FAILURE)
   if (!res)
@@ -52,11 +52,11 @@ void * operator new(std::size_t size) {
 #endif
   return res;
 }
-void * operator new[](std::size_t size) {
+[[gnu::weak]] void * operator new[](std::size_t size) {
   return operator new(size);
 }
 
-void * operator new(std::size_t size, [[gnu::unused]] const std::nothrow_t tag) noexcept {
+[[gnu::weak]] void * operator new(std::size_t size, [[gnu::unused]] const std::nothrow_t tag) noexcept {
 #if defined(NEW_TERMINATES_ON_FAILURE)
   // Cannot call throwing operator new as standard suggests, so call
   // new_helper directly then
@@ -65,7 +65,7 @@ void * operator new(std::size_t size, [[gnu::unused]] const std::nothrow_t tag)
   return operator new(size);
 #endif
 }
-void * operator new[](std::size_t size, [[gnu::unused]] const std::nothrow_t& tag) noexcept {
+[[gnu::weak]] void * operator new[](std::size_t size, [[gnu::unused]] const std::nothrow_t& tag) noexcept {
 #if defined(NEW_TERMINATES_ON_FAILURE)
   // Cannot call throwing operator new[] as standard suggests, so call
   // malloc directly then
@@ -84,26 +84,26 @@ void * operator new[](std::size_t size, void *place) noexcept {
   return operator new(size, place);
 }
 
-void operator delete(void * ptr) noexcept {
+[[gnu::weak]] void operator delete(void * ptr) noexcept {
   free(ptr);
 }
-void operator delete[](void * ptr) noexcept {
+[[gnu::weak]] void operator delete[](void * ptr) noexcept {
   operator delete(ptr);
 }
 
 #if __cplusplus >= 201402L
-void operator delete(void* ptr, std::size_t size) noexcept {
+[[gnu::weak]] void operator delete(void* ptr, std::size_t size) noexcept {
   operator delete(ptr);
 }
-void operator delete[](void * ptr, std::size_t size) noexcept {
+[[gnu::weak]] void operator delete[](void * ptr, std::size_t size) noexcept {
   operator delete[](ptr);
 }
 #endif // __cplusplus >= 201402L
 
-void operator delete(void* ptr, [[gnu::unused]] const std::nothrow_t& tag) noexcept {
+[[gnu::weak]] void operator delete(void* ptr, [[gnu::unused]] const std::nothrow_t& tag) noexcept {
   operator delete(ptr);
 }
-void operator delete[](void* ptr, [[gnu::unused]] const std::nothrow_t& tag) noexcept {
+[[gnu::weak]] void operator delete[](void* ptr, [[gnu::unused]] const std::nothrow_t& tag) noexcept {
   operator delete[](ptr);
 }