From 9a02bd8043c41f6ee57f136083ffc8bf8ec2bdc9 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Thu, 17 Sep 2020 19:29:31 +0200 Subject: Swap new and new.h header files Originally, the Arduino core used "new.h", rather than the standard "new", probably because the implementation was incomplete, and for the most commonly used new and delete operators, no include is needed at all (they are defined implicitly by the compiler). However, now Arduino does expose the "new" name, as an alias for the older "new.h". Given that the standard name is "new", it makes more sense to put the actual content in "new", and make "new.h" a compatibility header that includes "new" instead of the other way around. --- cores/arduino/new | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'cores/arduino/new') diff --git a/cores/arduino/new b/cores/arduino/new index aa8ecb5..763f5cc 100644 --- a/cores/arduino/new +++ b/cores/arduino/new @@ -1,5 +1,31 @@ /* -this header is for compatibility with standard c++ header names -so that #include works as expected + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "new.h" + +#ifndef NEW_H +#define NEW_H + +#include + +void * operator new(size_t size); +void * operator new[](size_t size); +void * operator new(size_t size, void * ptr) noexcept; +void operator delete(void * ptr); +void operator delete[](void * ptr); + +#endif + -- cgit v1.2.3-18-g5258 From 07b6bd188f2395551fbd5eee3c3ca7ca3769bbbc Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Thu, 17 Sep 2020 17:15:42 +0200 Subject: Clean up and complete `` header This makes this header complete up to including C++14, except two exception classes that cannot be defined without ``. The functions related to the "new_handler" are declared but not actually defined, to prevent overhead and complexity. They are still declared to allow implementing them in user code if needed. This makes the implementation of all operator new and delete functions comply with the C++11/C++14 specification in terms of which should be actually implemented and which should be delegate to other functions. There are still some areas where these implementations are not entirely standards-compliant, which will be fixed in subsequent commits. This fixes part of #287 and fixes #47. --- cores/arduino/new | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'cores/arduino/new') diff --git a/cores/arduino/new b/cores/arduino/new index 763f5cc..3599571 100644 --- a/cores/arduino/new +++ b/cores/arduino/new @@ -21,11 +21,40 @@ #include +namespace std { + struct nothrow_t {}; + extern const nothrow_t nothrow; + + // These are not actually implemented, to prevent overhead and + // complexity. They are still declared to allow implementing + // them in user code if needed. + typedef void (*new_handler)(); + new_handler set_new_handler(new_handler new_p) noexcept; + new_handler get_new_handler() noexcept; +} // namespace std + void * operator new(size_t size); void * operator new[](size_t size); -void * operator new(size_t size, void * ptr) noexcept; -void operator delete(void * ptr); -void operator delete[](void * ptr); + +void * operator new(size_t size, const std::nothrow_t tag) noexcept; +void * operator new[](size_t size, const std::nothrow_t& tag) noexcept; + +void * operator new(size_t size, void *place) noexcept; +void * operator new[](size_t size, void *place) noexcept; + +void operator delete(void * ptr) noexcept; +void operator delete[](void * ptr) noexcept; + +#if __cplusplus >= 201402L +void operator delete(void* ptr, size_t size) noexcept; +void operator delete[](void * ptr, size_t size) noexcept; +#endif // __cplusplus >= 201402L + +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; #endif -- cgit v1.2.3-18-g5258 From 4e469e0c83799ad6d3698e7cfa51ef8a5f2a2c76 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Thu, 17 Sep 2020 17:22:41 +0200 Subject: Allow overriding selected operator new and delete functions This makes these functions weak, so that a sketch or library can replace them. This does not apply to all of these operators, only for the ones that the C++ standard specifies as replaceable. --- cores/arduino/new | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'cores/arduino/new') diff --git a/cores/arduino/new b/cores/arduino/new index 3599571..fb60927 100644 --- a/cores/arduino/new +++ b/cores/arduino/new @@ -33,25 +33,25 @@ namespace std { new_handler get_new_handler() noexcept; } // namespace std -void * operator new(size_t size); -void * operator new[](size_t size); +[[gnu::weak]] void * operator new(size_t size); +[[gnu::weak]] void * operator new[](size_t size); -void * operator new(size_t size, const std::nothrow_t tag) noexcept; -void * operator new[](size_t size, const std::nothrow_t& tag) noexcept; +[[gnu::weak]] void * operator new(size_t size, const std::nothrow_t tag) noexcept; +[[gnu::weak]] void * operator new[](size_t size, const std::nothrow_t& tag) noexcept; void * operator new(size_t size, void *place) noexcept; void * operator new[](size_t size, void *place) noexcept; -void operator delete(void * ptr) noexcept; -void operator delete[](void * ptr) noexcept; +[[gnu::weak]] void operator delete(void * ptr) noexcept; +[[gnu::weak]] void operator delete[](void * ptr) noexcept; #if __cplusplus >= 201402L -void operator delete(void* ptr, size_t size) noexcept; -void operator delete[](void * ptr, size_t size) noexcept; +[[gnu::weak]] void operator delete(void* ptr, size_t size) noexcept; +[[gnu::weak]] void operator delete[](void * ptr, size_t size) noexcept; #endif // __cplusplus >= 201402L -void operator delete(void* ptr, const std::nothrow_t& tag) noexcept; -void operator delete[](void* ptr, const std::nothrow_t& tag) noexcept; +[[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, void* place) noexcept; void operator delete[](void* ptr, void* place) noexcept; -- cgit v1.2.3-18-g5258 From 6d292502e138b5c73705f0df8095ded3f1df956f Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Thu, 17 Sep 2020 19:43:09 +0200 Subject: Use std::size_t in new/delete The standard dictates that `std::size_t` is used, rather than the plain `size_t` type. Even though these types are usually, if not always, exactly the same type, other code might assume that `std::size_t` is actually used and thus also available under that name after including ``. This fixes that by using the right type. One challenge is that it is usually declared in headers that we do not have available, so this just defines the `std::size_t` type in the `` header to work around that. --- cores/arduino/new | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'cores/arduino/new') diff --git a/cores/arduino/new b/cores/arduino/new index fb60927..8cf2103 100644 --- a/cores/arduino/new +++ b/cores/arduino/new @@ -31,23 +31,29 @@ namespace std { typedef void (*new_handler)(); new_handler set_new_handler(new_handler new_p) noexcept; new_handler get_new_handler() noexcept; + + // This is normally declared in various headers that we do not have + // available, so just define it here. We could also use ::size_t + // below, but then anyone including can no longer assume + // std::size_t is available. + using size_t = ::size_t; } // namespace std -[[gnu::weak]] void * operator new(size_t size); -[[gnu::weak]] void * operator new[](size_t size); +[[gnu::weak]] void * operator new(std::size_t size); +[[gnu::weak]] void * operator new[](std::size_t size); -[[gnu::weak]] void * operator new(size_t size, const std::nothrow_t tag) noexcept; -[[gnu::weak]] void * operator new[](size_t size, const std::nothrow_t& tag) noexcept; +[[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(size_t size, void *place) noexcept; -void * operator new[](size_t size, void *place) 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; #if __cplusplus >= 201402L -[[gnu::weak]] void operator delete(void* ptr, size_t size) noexcept; -[[gnu::weak]] void operator delete[](void * ptr, size_t size) noexcept; +[[gnu::weak]] void operator delete(void* ptr, std::size_t size) noexcept; +[[gnu::weak]] 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; -- cgit v1.2.3-18-g5258