[libcxx-commits] [libcxx] [libcxx] Improve handling of DummyData blocks in libcxx tests (PR #88897)
Jack Styles via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Apr 17 05:44:03 PDT 2024
https://github.com/Stylie777 updated https://github.com/llvm/llvm-project/pull/88897
>From 82bf517d4cd84672aaeb4ec632ec21c3e41b225b Mon Sep 17 00:00:00 2001
From: Jack Styles <jack.styles at arm.com>
Date: Tue, 16 Apr 2024 11:55:54 +0100
Subject: [PATCH 1/2] [libcxx] Update libcxx tests to better utilise
`DoNotOptimize`
As part of the libcxx tests, there is a function provided called `DoNotOptimize`.
The tests currently utilise a version which only uses the value as an input,
leading to the compiler not removing information relating to the data-flow for
the value. This led to issues when comparing the pointer values, where one is a
global pointer and the other a pointer which is local to the function being
executed.
Another version of `DoNotOptimize` is available which allows for the value
to be an input and output of the inline assembley, which allows for the
pointers to be successfully compared to one another. To utilize this function
the `new` operator should be called beforehand, the pointer stored in its own
variable and then this passed to the `DoNotOptimize` variable.
---
.../new.delete.array/new.size_align.replace.indirect.pass.cpp | 3 ++-
.../new.size_align_nothrow.replace.indirect.pass.cpp | 3 ++-
.../new.size_align_nothrow.replace.indirect.pass.cpp | 3 ++-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp
index 0b540e09bab3cc..b68cad9968d39b 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp
@@ -51,7 +51,8 @@ int main(int, char**) {
// Test with an overaligned type
{
new_called = delete_called = 0;
- OverAligned* x = DoNotOptimize(new OverAligned[3]);
+ OverAligned* dummy_data_block = new OverAligned;
+ OverAligned* x = DoNotOptimize(dummy_data_block);
ASSERT_WITH_OPERATOR_NEW_FALLBACKS(static_cast<void*>(x) == DummyData);
ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1);
diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp
index 227b20f0b1e18b..4085e92642cd64 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp
@@ -55,7 +55,8 @@ int main(int, char**) {
// Test with an overaligned type
{
new_called = delete_called = 0;
- OverAligned* x = DoNotOptimize(new (std::nothrow) OverAligned[3]);
+ OverAligned* dummy_data_block = new (std::nothrow) OverAligned[3];
+ OverAligned* x = DoNotOptimize(dummy_data_block);
ASSERT_WITH_OPERATOR_NEW_FALLBACKS(static_cast<void*>(x) == DummyData);
ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1);
diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp
index 7eab0729f9ef1a..543ab76d4e1c51 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp
@@ -54,7 +54,8 @@ int main(int, char**) {
// Test with an overaligned type
{
new_called = delete_called = 0;
- OverAligned* x = DoNotOptimize(new (std::nothrow) OverAligned);
+ OverAligned* dummy_data_block = new (std::nothrow) OverAligned;
+ OverAligned* x = DoNotOptimize(dummy_data_block);
ASSERT_WITH_OPERATOR_NEW_FALLBACKS(static_cast<void*>(x) == DummyData);
ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1);
>From f765ebe6e595e63c47c5a654f968e753c1bbcc76 Mon Sep 17 00:00:00 2001
From: Jack Styles <jack.styles at arm.com>
Date: Wed, 17 Apr 2024 08:44:31 +0100
Subject: [PATCH 2/2] [libcxx] Better define the DummyData for tests
The tests utilise a DummyData block to assign a block of memory rather than
calling `malloc` and `free` as part of `new` and `delete` operations. However,
this is defined as a global variable which causes issues when comparing the
memory address to the locally stored variable within the test.
To get around this, the DummyData block is now part of a class, which
is defined globally. This is then used to compare the pointers and ensure
the operations are working correctly.
---
.../new.size_align.replace.pass.cpp | 26 ++++++++++++++-----
.../new.size_align.replace.pass.cpp | 26 ++++++++++++++-----
.../new.size_align_nothrow.replace.pass.cpp | 26 ++++++++++++++-----
3 files changed, 57 insertions(+), 21 deletions(-)
diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.pass.cpp
index 2d021ecb30e793..278d7801b3ab71 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.pass.cpp
@@ -27,16 +27,28 @@
#include "test_macros.h"
#include "../types.h"
+class Data {
+public:
+ Data() = default;
+ ~Data() = default;
+
+ char* getDummyData() { return this->dummy_data_; }
+
+ std::size_t getDummyDataSize() { return sizeof(this->dummy_data_); }
+
+private:
+ alignas(OverAligned) char dummy_data_[alignof(OverAligned) * 3];
+};
+
int new_called = 0;
int delete_called = 0;
-
-alignas(OverAligned) char DummyData[alignof(OverAligned) * 3];
+Data data_class;
void* operator new[](std::size_t s, std::align_val_t a) {
- assert(s <= sizeof(DummyData));
- assert(static_cast<std::size_t>(a) == alignof(OverAligned));
- ++new_called;
- return DummyData;
+ assert(s <= data_class.getDummyDataSize());
+ assert(static_cast<std::size_t>(a) == alignof(OverAligned));
+ ++new_called;
+ return data_class.getDummyData();
}
void operator delete[](void*, std::align_val_t) noexcept {
@@ -49,7 +61,7 @@ int main(int, char**) {
{
new_called = delete_called = 0;
OverAligned* x = new OverAligned[3];
- assert(static_cast<void*>(x) == DummyData);
+ assert(static_cast<void*>(x) == data_class.getDummyData());
assert(new_called == 1);
delete[] x;
diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.replace.pass.cpp
index e5ef5f1669752b..82fdcb6a3e5b70 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.replace.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.replace.pass.cpp
@@ -27,16 +27,28 @@
#include "test_macros.h"
#include "../types.h"
+class Data {
+public:
+ Data() = default;
+ ~Data() = default;
+
+ char* getDummyData() { return this->dummy_data_; }
+
+ std::size_t getDummyDataSize() { return sizeof(this->dummy_data_); }
+
+private:
+ alignas(OverAligned) char dummy_data_[alignof(OverAligned)];
+};
+
int new_called = 0;
int delete_called = 0;
-
-alignas(OverAligned) char DummyData[alignof(OverAligned)];
+Data data_class;
void* operator new(std::size_t s, std::align_val_t a) {
- assert(s <= sizeof(DummyData));
- assert(static_cast<std::size_t>(a) == alignof(OverAligned));
- ++new_called;
- return DummyData;
+ assert(s <= data_class.getDummyDataSize());
+ assert(static_cast<std::size_t>(a) == alignof(OverAligned));
+ ++new_called;
+ return data_class.getDummyData();
}
void operator delete(void*, std::align_val_t) noexcept {
@@ -49,7 +61,7 @@ int main(int, char**) {
{
new_called = delete_called = 0;
OverAligned* x = new OverAligned;
- assert(static_cast<void*>(x) == DummyData);
+ assert(static_cast<void*>(x) == data_class.getDummyData());
assert(new_called == 1);
delete x;
diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.pass.cpp
index 9a5b53e039025c..60ace3582baa84 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.pass.cpp
@@ -26,16 +26,28 @@
#include "test_macros.h"
#include "../types.h"
+class Data {
+public:
+ Data() = default;
+ ~Data() = default;
+
+ char* getDummyData() { return this->dummy_data_; }
+
+ std::size_t getDummyDataSize() { return sizeof(this->dummy_data_); }
+
+private:
+ alignas(OverAligned) char dummy_data_[alignof(OverAligned)];
+};
+
int new_nothrow_called = 0;
int delete_called = 0;
-
-alignas(OverAligned) char DummyData[alignof(OverAligned)];
+Data data_class;
void* operator new(std::size_t s, std::align_val_t a, std::nothrow_t const&) noexcept {
- assert(s <= sizeof(DummyData));
- assert(static_cast<std::size_t>(a) == alignof(OverAligned));
- ++new_nothrow_called;
- return DummyData;
+ assert(s <= data_class.getDummyDataSize());
+ assert(static_cast<std::size_t>(a) == alignof(OverAligned));
+ ++new_nothrow_called;
+ return data_class.getDummyData();
}
void operator delete(void*, std::align_val_t) noexcept {
@@ -48,7 +60,7 @@ int main(int, char**) {
{
new_nothrow_called = delete_called = 0;
OverAligned* x = new (std::nothrow) OverAligned;
- assert(static_cast<void*>(x) == DummyData);
+ assert(static_cast<void*>(x) == data_class.getDummyData());
ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_nothrow_called == 1);
delete x;
More information about the libcxx-commits
mailing list