changeset 70:fb265a6efea1 trunk

[svn r74] Fixed passing types with different alignment to D-style variadic functions. Fixed casting integer to pointer.
author lindquist
date Sun, 28 Oct 2007 19:33:50 +0100
parents 2b5a2eaa88be
children 53d3086b5ad3
files gen/toir.c lphobos/std/stdarg.d test/vararg4.d
diffstat 3 files changed, 42 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/gen/toir.c	Sun Oct 28 04:23:38 2007 +0100
+++ b/gen/toir.c	Sun Oct 28 19:33:50 2007 +0100
@@ -1287,6 +1287,9 @@
                 e->val = new llvm::SIToFPInst(u->getValue(), tolltype, "tmp", p->scopebb());
             }
         }
+        else if (totype->ty == Tpointer) {
+            e->val = p->ir->CreateIntToPtr(u->getValue(), tolltype, "tmp");
+        }
         else {
             assert(0);
         }
--- a/lphobos/std/stdarg.d	Sun Oct 28 04:23:38 2007 +0100
+++ b/lphobos/std/stdarg.d	Sun Oct 28 19:33:50 2007 +0100
@@ -12,7 +12,8 @@
 
 T va_arg(T)(inout va_list vp)
 {
-    va_list vptmp = vp;
-    vp += T.sizeof;
+    static assert((T.sizeof & (T.sizeof -1)) == 0);
+    va_list vptmp = cast(va_list)((cast(size_t)vp + T.sizeof - 1) &  ~(T.sizeof - 1));
+    vp = vptmp + T.sizeof;
     return *cast(T*)vptmp;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/vararg4.d	Sun Oct 28 19:33:50 2007 +0100
@@ -0,0 +1,36 @@
+module vararg4;
+import std.stdarg;
+
+void vafunc(...)
+{
+    foreach(i,v; _arguments) {
+        if (typeid(byte) == v) {
+            printf("byte(%d)\n", va_arg!(byte)(_argptr));
+        }
+        else if (typeid(short) == v) {
+            printf("short(%d)\n", va_arg!(short)(_argptr));
+        }
+        else if (typeid(int) == v) {
+            printf("int(%d)\n", va_arg!(int)(_argptr));
+        }
+        else if (typeid(long) == v) {
+            printf("long(%ld)\n", va_arg!(long)(_argptr));
+        }
+        else if (typeid(float) == v) {
+            printf("float(%f)\n", va_arg!(float)(_argptr));
+        }
+        else if (typeid(double) == v) {
+            printf("double(%f)\n", va_arg!(double)(_argptr));
+        }
+        else if (typeid(real) == v) {
+            printf("real(%f)\n", va_arg!(real)(_argptr));
+        }
+        else
+        assert(0, "unsupported type");
+    }
+}
+
+void main()
+{
+    vafunc(byte.max,short.max,1,2,3,4L,5.0f,6.0,cast(real)7);
+}