Skip to content

Commit 6ec8015

Browse files
authored
Merge pull request #361 from matthijskooijman/improve-new
Improve and complete implementation of new/delete
2 parents 3055c1e + 6d29250 commit 6ec8015

File tree

4 files changed

+161
-51
lines changed

4 files changed

+161
-51
lines changed

Diff for: cores/arduino/abi.cpp

+8-7
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@
2121
extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__));
2222
extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
2323

24+
namespace std {
25+
[[gnu::weak, noreturn]] void terminate() {
26+
abort();
27+
}
28+
}
29+
2430
void __cxa_pure_virtual(void) {
25-
// We might want to write some diagnostics to uart in this case
26-
//std::terminate();
27-
abort();
31+
std::terminate();
2832
}
2933

3034
void __cxa_deleted_virtual(void) {
31-
// We might want to write some diagnostics to uart in this case
32-
//std::terminate();
33-
abort();
35+
std::terminate();
3436
}
35-

Diff for: cores/arduino/new

+64-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,66 @@
11
/*
2-
this header is for compatibility with standard c++ header names
3-
so that #include<new> works as expected
2+
Copyright (c) 2014 Arduino. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
417
*/
5-
#include "new.h"
18+
19+
#ifndef NEW_H
20+
#define NEW_H
21+
22+
#include <stdlib.h>
23+
24+
namespace std {
25+
struct nothrow_t {};
26+
extern const nothrow_t nothrow;
27+
28+
// These are not actually implemented, to prevent overhead and
29+
// complexity. They are still declared to allow implementing
30+
// them in user code if needed.
31+
typedef void (*new_handler)();
32+
new_handler set_new_handler(new_handler new_p) noexcept;
33+
new_handler get_new_handler() noexcept;
34+
35+
// This is normally declared in various headers that we do not have
36+
// available, so just define it here. We could also use ::size_t
37+
// below, but then anyone including <new> can no longer assume
38+
// std::size_t is available.
39+
using size_t = ::size_t;
40+
} // namespace std
41+
42+
[[gnu::weak]] void * operator new(std::size_t size);
43+
[[gnu::weak]] void * operator new[](std::size_t size);
44+
45+
[[gnu::weak]] void * operator new(std::size_t size, const std::nothrow_t tag) noexcept;
46+
[[gnu::weak]] void * operator new[](std::size_t size, const std::nothrow_t& tag) noexcept;
47+
48+
void * operator new(std::size_t size, void *place) noexcept;
49+
void * operator new[](std::size_t size, void *place) noexcept;
50+
51+
[[gnu::weak]] void operator delete(void * ptr) noexcept;
52+
[[gnu::weak]] void operator delete[](void * ptr) noexcept;
53+
54+
#if __cplusplus >= 201402L
55+
[[gnu::weak]] void operator delete(void* ptr, std::size_t size) noexcept;
56+
[[gnu::weak]] void operator delete[](void * ptr, std::size_t size) noexcept;
57+
#endif // __cplusplus >= 201402L
58+
59+
[[gnu::weak]] void operator delete(void* ptr, const std::nothrow_t& tag) noexcept;
60+
[[gnu::weak]] void operator delete[](void* ptr, const std::nothrow_t& tag) noexcept;
61+
62+
void operator delete(void* ptr, void* place) noexcept;
63+
void operator delete[](void* ptr, void* place) noexcept;
64+
65+
#endif
66+

Diff for: cores/arduino/new.cpp

+86-10
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,102 @@
1616
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1717
*/
1818

19-
#include <stdlib.h>
19+
#include "new.h"
2020

21-
void *operator new(size_t size) {
22-
return malloc(size);
21+
// The C++ spec dicates that allocation failure should cause the
22+
// (non-nothrow version of the) operator new to throw an exception.
23+
// Since we expect to have exceptions disabled, it would be more
24+
// appropriate (and probably standards-compliant) to terminate instead.
25+
// Historically failure causes null to be returned, but this define
26+
// allows switching to more robust terminating behaviour (that might
27+
// become the default at some point in the future). Note that any code
28+
// that wants null to be returned can (and should) use the nothrow
29+
// versions of the new statement anyway and is unaffected by this.
30+
// #define NEW_TERMINATES_ON_FAILURE
31+
32+
namespace std {
33+
// Defined in abi.cpp
34+
void terminate();
35+
36+
const nothrow_t nothrow;
2337
}
2438

25-
void *operator new[](size_t size) {
39+
static void * new_helper(std::size_t size) {
40+
// Even zero-sized allocations should return a unique pointer, but
41+
// malloc does not guarantee this
42+
if (size == 0)
43+
size = 1;
2644
return malloc(size);
2745
}
2846

29-
void * operator new(size_t size, void * ptr) noexcept {
30-
(void)size;
31-
return ptr;
47+
void * operator new(std::size_t size) {
48+
void *res = new_helper(size);
49+
#if defined(NEW_TERMINATES_ON_FAILURE)
50+
if (!res)
51+
std::terminate();
52+
#endif
53+
return res;
54+
}
55+
void * operator new[](std::size_t size) {
56+
return operator new(size);
3257
}
3358

34-
void operator delete(void * ptr) {
35-
free(ptr);
59+
void * operator new(std::size_t size, const std::nothrow_t tag) noexcept {
60+
#if defined(NEW_TERMINATES_ON_FAILURE)
61+
// Cannot call throwing operator new as standard suggests, so call
62+
// new_helper directly then
63+
return new_helper(size);
64+
#else
65+
return operator new(size);
66+
#endif
67+
}
68+
void * operator new[](std::size_t size, const std::nothrow_t& tag) noexcept {
69+
#if defined(NEW_TERMINATES_ON_FAILURE)
70+
// Cannot call throwing operator new[] as standard suggests, so call
71+
// malloc directly then
72+
return new_helper(size);
73+
#else
74+
return operator new[](size);
75+
#endif
76+
}
77+
78+
void * operator new(std::size_t size, void *place) noexcept {
79+
// Nothing to do
80+
(void)size; // unused
81+
return place;
82+
}
83+
void * operator new[](std::size_t size, void *place) noexcept {
84+
return operator new(size, place);
3685
}
3786

38-
void operator delete[](void * ptr) {
87+
void operator delete(void * ptr) noexcept {
3988
free(ptr);
4089
}
90+
void operator delete[](void * ptr) noexcept {
91+
operator delete(ptr);
92+
}
4193

94+
#if __cplusplus >= 201402L
95+
void operator delete(void* ptr, std::size_t size) noexcept {
96+
operator delete(ptr);
97+
}
98+
void operator delete[](void * ptr, std::size_t size) noexcept {
99+
operator delete[](ptr);
100+
}
101+
#endif // __cplusplus >= 201402L
102+
103+
void operator delete(void* ptr, const std::nothrow_t& tag) noexcept {
104+
operator delete(ptr);
105+
}
106+
void operator delete[](void* ptr, const std::nothrow_t& tag) noexcept {
107+
operator delete[](ptr);
108+
}
109+
110+
void operator delete(void* ptr, void* place) noexcept {
111+
(void)ptr; (void)place; // unused
112+
// Nothing to do
113+
}
114+
void operator delete[](void* ptr, void* place) noexcept {
115+
(void)ptr; (void)place; // unused
116+
// Nothing to do
117+
}

Diff for: cores/arduino/new.h

+3-31
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,3 @@
1-
/*
2-
Copyright (c) 2014 Arduino. All right reserved.
3-
4-
This library is free software; you can redistribute it and/or
5-
modify it under the terms of the GNU Lesser General Public
6-
License as published by the Free Software Foundation; either
7-
version 2.1 of the License, or (at your option) any later version.
8-
9-
This library is distributed in the hope that it will be useful,
10-
but WITHOUT ANY WARRANTY; without even the implied warranty of
11-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12-
See the GNU Lesser General Public License for more details.
13-
14-
You should have received a copy of the GNU Lesser General Public
15-
License along with this library; if not, write to the Free Software
16-
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17-
*/
18-
19-
#ifndef NEW_H
20-
#define NEW_H
21-
22-
#include <stdlib.h>
23-
24-
void * operator new(size_t size);
25-
void * operator new[](size_t size);
26-
void * operator new(size_t size, void * ptr) noexcept;
27-
void operator delete(void * ptr);
28-
void operator delete[](void * ptr);
29-
30-
#endif
31-
1+
// This file originally used a non-standard name for this Arduino core
2+
// only, so still expose the old new.h name for compatibility.
3+
#include "new"

0 commit comments

Comments
 (0)