diff --git a/alloc/raw/aligned/foreign.hpp b/alloc/raw/aligned/foreign.hpp index 8df882bf..946863fa 100644 --- a/alloc/raw/aligned/foreign.hpp +++ b/alloc/raw/aligned/foreign.hpp @@ -37,19 +37,31 @@ namespace util::alloc::raw::aligned { /// /// This approach will explode if a child allocator wants to write to the /// range, so the user is mostly restricted to very simple allocators - /// (like 'linear'). This is why we use a view based at nullptr; any - /// mistaken access is quite a lot more likely to fault here. + /// (like 'linear'). + /// + /// We supply a proxy view at the (probably) invalid address: + /// (void*)alignment + /// This removes any potential bias in the successor allocators. We very + /// specifically cannot use nullptr because it breaks under optimisations + /// due to undefined behaviour of null pointers. + /// + /// The proxy view will _probably_ result in a segfault if the successor + /// allocator attempts to read/write directly to it given typical + /// alignments will give addresses far below typical mappings. template class foreign { public: template foreign (util::view _data, std::size_t _alignment, Args &&...args): m_successor ( - view {0, _data.size ()}, + view { + reinterpret_cast (_alignment), + reinterpret_cast (_alignment + _data.size ()), + }, _alignment, std::forward (args)... ), - m_offset (m_successor.data () - _data.data ()), + m_offset (_data.data () - m_successor.data ()), m_alignment (_alignment) { ; } @@ -60,14 +72,14 @@ namespace util::alloc::raw::aligned { auto ptr= reinterpret_cast ( m_successor.allocate (size) ); - return ptr - m_offset; + return ptr + m_offset; } auto deallocate (void *ptr, std::size_t size) { return m_successor.deallocate ( - reinterpret_cast (ptr) + m_offset, size + reinterpret_cast (ptr) - m_offset, size ); } @@ -76,18 +88,18 @@ namespace util::alloc::raw::aligned { auto offset (const void *ptr) const { return m_successor.offset ( - reinterpret_cast (ptr) + m_offset + reinterpret_cast (ptr) - m_offset ); } - auto data (void) { return m_successor.data () - m_offset; } - auto data (void) const { return m_successor.data () - m_offset; } + auto data (void) { return m_successor.data () + m_offset; } + auto data (void) const { return m_successor.data () + m_offset; } - auto begin (void) { return m_successor.begin () - m_offset; } - auto begin (void) const { return m_successor.begin () - m_offset; } + auto begin (void) { return m_successor.begin () + m_offset; } + auto begin (void) const { return m_successor.begin () + m_offset; } - auto end (void) { return m_successor.end () - m_offset; } - auto end (void) const { return m_successor.end () - m_offset; } + auto end (void) { return m_successor.end () + m_offset; } + auto end (void) const { return m_successor.end () + m_offset; } auto reset (void) { return m_successor.reset (); } @@ -96,7 +108,6 @@ namespace util::alloc::raw::aligned { auto remain (void) const { return m_successor.remain (); } private: - direct m_successor; std::ptrdiff_t m_offset; std::size_t m_alignment;