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