changeset 1330:459b6b6f9a8d

Fixed D-style vararg arguments with types that have sizes bigger that pointers, yet are not aligned to pointer sizes. Fixes ticket #276 .
author Tomas Lindquist Olsen <tomas.l.olsen gmail com>
date Sun, 10 May 2009 04:37:03 +0200
parents e5b57fd8307c
children 1565b33a6ecb
files gen/tocall.cpp
diffstat 1 files changed, 22 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/gen/tocall.cpp	Sun May 10 04:18:14 2009 +0200
+++ b/gen/tocall.cpp	Sun May 10 04:37:03 2009 +0200
@@ -141,8 +141,28 @@
         assert(argexp->type->ty != Ttuple);
         vtypes.push_back(DtoType(argexp->type));
         size_t sz = getTypePaddedSize(vtypes.back());
-        if (sz < PTRSIZE)
-            vtypes.back() = DtoSize_t();
+        size_t asz = (sz + PTRSIZE - 1) & ~(PTRSIZE -1);
+        if (sz != asz)
+        {
+            if (sz < PTRSIZE)
+            {
+                vtypes.back() = DtoSize_t();
+            }
+            else
+            {
+                // ok then... so we build some type that is big enough
+                // and aligned to PTRSIZE
+                std::vector<const LLType*> gah;
+                gah.reserve(asz/PTRSIZE);
+                size_t gah_sz = 0;
+                while (gah_sz < asz)
+                {
+                    gah.push_back(DtoSize_t());
+                    gah_sz += PTRSIZE;
+                }
+                vtypes.back() = LLStructType::get(gah, true);
+            }
+        }
     }
     const LLStructType* vtype = LLStructType::get(vtypes);