From a2cdcb1ff387b16afb6026599d349977757ae820 Mon Sep 17 00:00:00 2001 From: Santiago Ospina De Los Rios <sospinar@gmail.com> Date: Wed, 27 Nov 2024 19:15:42 +0100 Subject: [PATCH] Throw before reaching undefined behavior on AlignedNumber allocation With this commit, AlignedNumber throws an exception whenever a placement new is made with a misaligned address. This should effectively catches an undefined behavior on the library implementations of operator new() under misaligned addresses. --- dune/common/test/debugaligntest.cc | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/dune/common/test/debugaligntest.cc b/dune/common/test/debugaligntest.cc index aa8fd1b46..ee218288f 100644 --- a/dune/common/test/debugaligntest.cc +++ b/dune/common/test/debugaligntest.cc @@ -11,6 +11,9 @@ #include <dune/common/test/arithmetictestsuite.hh> #include <dune/common/test/testsuite.hh> +//! Exception thrown when an object is allocated with a misaligned address +class MisalignedAddress : public Dune::RangeError {}; + class WithViolatedAlignmentHandler { Dune::ViolatedAlignmentHandler oldhandler; public: @@ -39,9 +42,8 @@ public: template<class T> void checkAlignmentViolation(Dune::TestSuite &test) { - bool misalignmentDetected = false; WithViolatedAlignmentHandler - guard([&](auto&&...){ misalignmentDetected = true; }); + guard([&](auto&&...){ throw MisalignedAddress{}; }); static_assert(alignof(T) <= sizeof(T)); char buffer[alignof(T)+sizeof(T)]; @@ -56,24 +58,18 @@ void checkAlignmentViolation(Dune::TestSuite &test) test.check(not Dune::isAligned(misalignedAddr, alignof(T)), "We could not misalign an address"); } - auto ptr = new(misalignedAddr) T; - test.check(misalignmentDetected, "default construct") - << "misalignment not detected for " << Dune::className<T>(); - - misalignmentDetected = false; - - ptr = new(misalignedAddr) T(T(0)); - test.check(misalignmentDetected, "move construct") - << "misalignment not detected for " << Dune::className<T>(); - ptr->~T(); + test.checkThrow<MisalignedAddress>([&]{ + auto ptr = new(misalignedAddr) T; + }, "default construct") << "misaligned address was not caught" << Dune::className<T>(); - misalignmentDetected = false; + test.checkThrow<MisalignedAddress>([&]{ + auto ptr = new(misalignedAddr) T(T(0)); + }, "move construct") << "misaligned address was not caught"; T t(0); - ptr = new(misalignedAddr) T(t); - test.check(misalignmentDetected, "copy construct") - << "misalignment not detected for " << Dune::className<T>(); - ptr->~T(); + test.checkThrow<MisalignedAddress>([&]{ + auto ptr = new(misalignedAddr) T(t); + }, "copy construct") << "misaligned address was not caught"; } int main(int argc, char **argv) -- GitLab