From: Modestas Vainius <modestas@vainius.eu>
Subject: [PATCH] Memory alignment fixes

Fixes various memory alignment issues which cause generator to crash on
alignment-sensitive architectures.

Signed-off-by: Modestas Vainius <modestas@vainius.eu>

---
 generator/parser/ast.h           |    2 +-
 generator/parser/list.h          |    2 +-
 generator/parser/rpp/pp-symbol.h |    9 +++++++--
 generator/parser/rxx_allocator.h |   17 +++++++++++++++++
 generator/parser/smallobject.h   |    6 ++++++
 5 files changed, 32 insertions(+), 4 deletions(-)

--- generator/parser/ast.h
+++ generator/parser/ast.h
@@ -880,7 +880,7 @@ struct QEnumsAST : public DeclarationAST
 template <class _Tp>
 _Tp *CreateNode(pool *memory_pool)
 {
-  _Tp *node = reinterpret_cast<_Tp*>(memory_pool->allocate(sizeof(_Tp)));
+  _Tp *node = reinterpret_cast<_Tp*>(memory_pool->allocate(sizeof(_Tp), strideof(_Tp)));
   node->kind = _Tp::__node_kind;
   return node;
 }
--- generator/parser/list.h
+++ generator/parser/list.h
@@ -54,7 +54,7 @@ struct ListNode
 
   static ListNode *create(const Tp &element, pool *p)
   {
-    ListNode<Tp> *node = new (p->allocate(sizeof(ListNode))) ListNode();
+    ListNode<Tp> *node = new (p->allocate(sizeof(ListNode), strideof(ListNode))) ListNode();
     node->element = element;
     node->index = 0;
     node->next = node;
--- generator/parser/rpp/pp-symbol.h
+++ generator/parser/rpp/pp-symbol.h
@@ -51,6 +51,11 @@ class pp_symbol
     static rxx_allocator<char>__allocator;
     return __allocator;
   }
+  static rxx_allocator<pp_fast_string> &ppfs_allocator_instance ()
+  {
+    static rxx_allocator<pp_fast_string>__ppfs_allocator;
+    return __ppfs_allocator;
+  }
 
 public:
   static int &N()
@@ -66,7 +71,7 @@ public:
     memcpy(data, __data, __size);
     data[__size] = '\0';
 
-    char *where = allocator_instance ().allocate (sizeof (pp_fast_string));
+    pp_fast_string *where = ppfs_allocator_instance ().allocate (sizeof (pp_fast_string));
     return new (where) pp_fast_string (data, __size);
   }
 
@@ -86,7 +91,7 @@ public:
     std::copy (__first, __last, data);
     data[__size] = '\0';
 
-    char *where = allocator_instance ().allocate (sizeof (pp_fast_string));
+    pp_fast_string *where = ppfs_allocator_instance ().allocate (sizeof (pp_fast_string));
     return new (where) pp_fast_string (data, __size);
   }
 
--- generator/parser/rxx_allocator.h
+++ generator/parser/rxx_allocator.h
@@ -48,6 +48,17 @@
 #include <cstring>
 #include <memory>
 
+// Stride calculation
+template <typename T>
+struct Tchar {
+  T t;
+  char c;
+};
+
+#define strideof(T)                            \
+  ((sizeof(Tchar<T>) > sizeof(T)) ?            \
+  sizeof(Tchar<T>)-sizeof(T) : sizeof(T))
+
 template <class _Tp> class rxx_allocator {
 public:
   typedef _Tp value_type;
@@ -106,6 +117,12 @@ public:
     return p;
   }
 
+  pointer allocate(size_type __n, size_type stride, const void* = 0) {
+    if (reinterpret_cast<size_type>(_M_current_block + _M_current_index) % stride > 0)
+      _M_current_index += stride - reinterpret_cast<size_type>(_M_current_block + _M_current_index) % stride;
+    return allocate(__n);
+  }
+
   void deallocate(pointer __p, size_type __n) {}
 
   size_type max_size() const { return size_type(-1) / sizeof(_Tp); }
--- generator/parser/smallobject.h
+++ generator/parser/smallobject.h
@@ -52,6 +52,7 @@ class pool
 
 public:
   inline void *allocate(std::size_t __size);
+  inline void *allocate(std::size_t __size, std::size_t __stride);
 };
 
 inline void *pool::allocate(std::size_t __size)
@@ -59,6 +60,11 @@ inline void *pool::allocate(std::size_t
   return __alloc.allocate(__size);
 }
 
+inline void *pool::allocate(std::size_t __size, std::size_t __stride)
+{
+  return __alloc.allocate(__size, __stride);
+}
+
 #endif
 
 // kate: space-indent on; indent-width 2; replace-tabs on;
