Skip to content

Commit df9ea0b

Browse files
committed
Use volatile to help prevent incorrect optimisations
1 parent 2dbccf0 commit df9ea0b

File tree

4 files changed

+48
-48
lines changed

4 files changed

+48
-48
lines changed

tests/memory_tracker.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
#include <cstdio>
55
#include <stdexcept>
66

7-
void* allocations[max_allocations];
8-
void* allocations_array[max_allocations];
9-
std::size_t allocations_bytes[max_allocations];
10-
std::size_t num_allocations = 0u;
11-
std::size_t size_allocations = 0u;
12-
std::size_t double_delete = 0u;
13-
bool memory_tracking = false;
14-
bool force_next_allocation_failure = false;
7+
volatile void* allocations[max_allocations];
8+
volatile void* allocations_array[max_allocations];
9+
volatile std::size_t allocations_bytes[max_allocations];
10+
volatile std::size_t num_allocations = 0u;
11+
volatile std::size_t size_allocations = 0u;
12+
volatile std::size_t double_delete = 0u;
13+
volatile bool memory_tracking = false;
14+
volatile bool force_next_allocation_failure = false;
1515

1616
constexpr bool debug_alloc = false;
1717
constexpr bool scramble_alloc = true;
@@ -93,8 +93,8 @@ void* allocate(std::size_t size, bool array, std::align_val_t align) {
9393

9494
allocations_bytes[num_allocations] = size;
9595

96-
++num_allocations;
97-
size_allocations += size;
96+
num_allocations = num_allocations + 1u;
97+
size_allocations = size_allocations + size;
9898
}
9999

100100
return p;
@@ -110,21 +110,21 @@ void deallocate(void* p, bool array, std::align_val_t align [[maybe_unused]]) {
110110
}
111111

112112
if (memory_tracking) {
113-
bool found = false;
114-
void** allocations_type = array ? allocations_array : allocations;
113+
bool found = false;
114+
volatile void** allocations_type = array ? allocations_array : allocations;
115115
for (std::size_t i = 0; i < num_allocations; ++i) {
116116
if (allocations_type[i] == p) {
117117
std::swap(allocations_type[i], allocations_type[num_allocations - 1]);
118118
std::swap(allocations_bytes[i], allocations_bytes[num_allocations - 1]);
119-
--num_allocations;
120-
size_allocations -= allocations_bytes[num_allocations - 1];
121-
found = true;
119+
num_allocations = num_allocations - 1u;
120+
size_allocations = size_allocations - allocations_bytes[num_allocations - 1];
121+
found = true;
122122
break;
123123
}
124124
}
125125

126126
if (!found) {
127-
++double_delete;
127+
double_delete = double_delete + 1u;
128128
}
129129
}
130130

@@ -188,11 +188,11 @@ memory_tracker::~memory_tracker() noexcept {
188188
::memory_tracking = false;
189189
}
190190

191-
std::size_t memory_tracker::allocated() const {
191+
std::size_t memory_tracker::allocated() const volatile {
192192
return ::num_allocations - initial_allocations;
193193
}
194194

195-
std::size_t memory_tracker::double_delete() const {
195+
std::size_t memory_tracker::double_delete() const volatile {
196196
return ::double_delete - initial_double_delete;
197197
}
198198

tests/memory_tracker.hpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
#include <new>
33

44
// Allocation tracker, to catch memory leaks and double delete
5-
constexpr std::size_t max_allocations = 20'000;
6-
extern void* allocations[max_allocations];
7-
extern void* allocations_array[max_allocations];
8-
extern std::size_t allocations_bytes[max_allocations];
9-
extern std::size_t num_allocations;
10-
extern std::size_t size_allocations;
11-
extern std::size_t double_delete;
12-
extern bool memory_tracking;
13-
extern bool force_next_allocation_failure;
5+
constexpr std::size_t max_allocations = 20'000;
6+
extern volatile void* allocations[max_allocations];
7+
extern volatile void* allocations_array[max_allocations];
8+
extern volatile std::size_t allocations_bytes[max_allocations];
9+
extern volatile std::size_t num_allocations;
10+
extern volatile std::size_t size_allocations;
11+
extern volatile std::size_t double_delete;
12+
extern volatile bool memory_tracking;
13+
extern volatile bool force_next_allocation_failure;
1414

1515
void* operator new(std::size_t size);
1616

@@ -39,8 +39,8 @@ struct memory_tracker {
3939
memory_tracker() noexcept;
4040
~memory_tracker() noexcept;
4141

42-
std::size_t allocated() const;
43-
std::size_t double_delete() const;
42+
std::size_t allocated() const volatile;
43+
std::size_t double_delete() const volatile;
4444
};
4545

4646
struct fail_next_allocation {

tests/runtime_tests_make_observable.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
TEMPLATE_LIST_TEST_CASE("make observable", "[make_observable][owner]", owner_types) {
66
if constexpr (can_use_make_observable<TestType>) {
7-
memory_tracker mem_track;
7+
volatile memory_tracker mem_track;
88

99
{
1010
TestType ptr = oup::make_observable<get_object<TestType>, get_policy<TestType>>();
@@ -28,7 +28,7 @@ TEMPLATE_LIST_TEST_CASE("make observable", "[make_observable][owner]", owner_typ
2828

2929
TEMPLATE_LIST_TEST_CASE("make observable with arguments", "[make_observable][owner]", owner_types) {
3030
if constexpr (can_use_make_observable<TestType>) {
31-
memory_tracker mem_track;
31+
volatile memory_tracker mem_track;
3232

3333
{
3434
TestType ptr = oup::make_observable<get_object<TestType>, get_policy<TestType>>(
@@ -54,7 +54,7 @@ TEMPLATE_LIST_TEST_CASE("make observable with arguments", "[make_observable][own
5454
TEMPLATE_LIST_TEST_CASE(
5555
"make observable throw in constructor", "[make_observable][owner]", owner_types) {
5656
if constexpr (can_use_make_observable<TestType>) {
57-
memory_tracker mem_track;
57+
volatile memory_tracker mem_track;
5858

5959
next_test_object_constructor_throws = true;
6060
REQUIRE_THROWS_AS(
@@ -67,7 +67,7 @@ TEMPLATE_LIST_TEST_CASE(
6767

6868
TEMPLATE_LIST_TEST_CASE("make observable bad alloc", "[make_observable][owner]", owner_types) {
6969
if constexpr (can_use_make_observable<TestType>) {
70-
memory_tracker mem_track;
70+
volatile memory_tracker mem_track;
7171

7272
force_next_allocation_failure = true;
7373
REQUIRE_THROWS_AS(
@@ -79,7 +79,7 @@ TEMPLATE_LIST_TEST_CASE("make observable bad alloc", "[make_observable][owner]",
7979

8080
TEST_CASE("make observable unique", "[make_observable][owner]") {
8181
using TestType = oup::observable_unique_ptr<test_object>;
82-
memory_tracker mem_track;
82+
volatile memory_tracker mem_track;
8383

8484
{
8585
TestType ptr = oup::make_observable_unique<test_object>();
@@ -95,7 +95,7 @@ TEST_CASE("make observable unique", "[make_observable][owner]") {
9595

9696
TEST_CASE("make observable sealed", "[make_observable][owner]") {
9797
using TestType = oup::observable_sealed_ptr<test_object>;
98-
memory_tracker mem_track;
98+
volatile memory_tracker mem_track;
9999

100100
{
101101
TestType ptr = oup::make_observable_sealed<test_object>();

tests/runtime_tests_observer_from_this.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
TEMPLATE_LIST_TEST_CASE("observer from this", "[observer_from_this]", owner_types) {
66
if constexpr (has_eoft<TestType>) {
7-
memory_tracker mem_track;
7+
volatile memory_tracker mem_track;
88

99
{
1010
TestType ptr = make_pointer_deleter_1<TestType>();
@@ -58,7 +58,7 @@ TEMPLATE_LIST_TEST_CASE("observer from this", "[observer_from_this]", owner_type
5858
TEMPLATE_LIST_TEST_CASE(
5959
"observer from this with no owner heap", "[observer_from_this]", owner_types) {
6060
if constexpr (has_eoft<TestType> && !must_use_make_observable<TestType>) {
61-
memory_tracker mem_track;
61+
volatile memory_tracker mem_track;
6262

6363
{
6464
get_object<TestType>* orig_ptr = make_instance<TestType>();
@@ -94,7 +94,7 @@ TEMPLATE_LIST_TEST_CASE(
9494

9595
TEMPLATE_LIST_TEST_CASE("observer from this no owner stack", "[observer_from_this]", owner_types) {
9696
if constexpr (has_eoft<TestType> && !eoft_constructor_takes_control_block<TestType>) {
97-
memory_tracker mem_track;
97+
volatile memory_tracker mem_track;
9898

9999
{
100100
get_object<TestType> obj;
@@ -128,7 +128,7 @@ TEMPLATE_LIST_TEST_CASE("observer from this no owner stack", "[observer_from_thi
128128
TEMPLATE_LIST_TEST_CASE(
129129
"observer from this acquired into base owner as base", "[observer_from_this]", owner_types) {
130130
if constexpr (has_eoft<TestType> && !must_use_make_observable<TestType>) {
131-
memory_tracker mem_track;
131+
volatile memory_tracker mem_track;
132132

133133
{
134134
get_object<TestType>* orig_ptr = make_instance<TestType>();
@@ -164,7 +164,7 @@ TEMPLATE_LIST_TEST_CASE(
164164
TEMPLATE_LIST_TEST_CASE(
165165
"observer from this acquired into base owner as derived", "[observer_from_this]", owner_types) {
166166
if constexpr (has_eoft<TestType> && has_base<TestType> && !must_use_make_observable<TestType>) {
167-
memory_tracker mem_track;
167+
volatile memory_tracker mem_track;
168168

169169
{
170170
get_object<TestType>* orig_ptr = make_instance<TestType>();
@@ -184,7 +184,7 @@ TEMPLATE_LIST_TEST_CASE(
184184
TEMPLATE_LIST_TEST_CASE(
185185
"observer from this after owner reset to empty", "[observer_from_this]", owner_types) {
186186
if constexpr (has_eoft<TestType>) {
187-
memory_tracker mem_track;
187+
volatile memory_tracker mem_track;
188188

189189
{
190190
TestType ptr = make_pointer_deleter_1<TestType>();
@@ -208,7 +208,7 @@ TEMPLATE_LIST_TEST_CASE(
208208
TEMPLATE_LIST_TEST_CASE(
209209
"observer from this after owner reset to valid", "[observer_from_this]", owner_types) {
210210
if constexpr (has_eoft<TestType> && can_reset_to_new<TestType>) {
211-
memory_tracker mem_track;
211+
volatile memory_tracker mem_track;
212212

213213
{
214214
TestType ptr = make_pointer_deleter_1<TestType>();
@@ -232,7 +232,7 @@ TEMPLATE_LIST_TEST_CASE(
232232
TEMPLATE_LIST_TEST_CASE(
233233
"observer from this after owner release", "[observer_from_this]", owner_types) {
234234
if constexpr (has_eoft<TestType> && can_release<TestType>) {
235-
memory_tracker mem_track;
235+
volatile memory_tracker mem_track;
236236

237237
{
238238
TestType ptr = make_pointer_deleter_1<TestType>();
@@ -264,7 +264,7 @@ TEMPLATE_LIST_TEST_CASE(
264264
"[observer_from_this]",
265265
owner_types) {
266266
if constexpr (has_eoft<TestType> && can_release<TestType> && can_reset_to_new<TestType>) {
267-
memory_tracker mem_track;
267+
volatile memory_tracker mem_track;
268268

269269
{
270270
TestType ptr = make_pointer_deleter_1<TestType>();
@@ -300,7 +300,7 @@ TEMPLATE_LIST_TEST_CASE(
300300
TEMPLATE_LIST_TEST_CASE(
301301
"observer from this after owner move", "[observer_from_this]", owner_types) {
302302
if constexpr (has_eoft<TestType>) {
303-
memory_tracker mem_track;
303+
volatile memory_tracker mem_track;
304304

305305
{
306306
TestType ptr1 = make_pointer_deleter_1<TestType>();
@@ -323,7 +323,7 @@ TEMPLATE_LIST_TEST_CASE(
323323
TEMPLATE_LIST_TEST_CASE(
324324
"observer from this after owner move assignment", "[observer_from_this]", owner_types) {
325325
if constexpr (has_eoft<TestType>) {
326-
memory_tracker mem_track;
326+
volatile memory_tracker mem_track;
327327

328328
{
329329
TestType ptr1 = make_pointer_deleter_1<TestType>();
@@ -353,7 +353,7 @@ TEST_CASE("observer from this multiple inheritance", "[observer_from_this]") {
353353
using eoft_deriv = oup::enable_observer_from_this_unique<deriv>;
354354
using TestType = ptr_deriv;
355355

356-
memory_tracker mem_track;
356+
volatile memory_tracker mem_track;
357357

358358
{
359359
deriv* raw_ptr_deriv = new deriv;
@@ -375,7 +375,7 @@ TEST_CASE("observer from this multiple inheritance", "[observer_from_this]") {
375375

376376
TEMPLATE_LIST_TEST_CASE("observer from this in constructor", "[observer_from_this]", owner_types) {
377377
if constexpr (has_eoft<TestType> && has_eoft_self_member<TestType>) {
378-
memory_tracker mem_track;
378+
volatile memory_tracker mem_track;
379379

380380
if constexpr (eoft_always_has_block<TestType>) {
381381
next_test_object_constructor_calls_observer_from_this = true;

0 commit comments

Comments
 (0)