From 449db38d7532f1a3d868ef27de06880e9c8609c4 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Sun, 28 Oct 2007 19:33:50 +0100 Subject: [PATCH] [svn r74] Fixed passing types with different alignment to D-style variadic functions. Fixed casting integer to pointer. --- gen/toir.c | 3 +++ lphobos/std/stdarg.d | 5 +++-- test/vararg4.d | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 test/vararg4.d diff --git a/gen/toir.c b/gen/toir.c index d71b6d48..0b62fa0b 100644 --- a/gen/toir.c +++ b/gen/toir.c @@ -1287,6 +1287,9 @@ elem* CastExp::toElem(IRState* p) 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); } diff --git a/lphobos/std/stdarg.d b/lphobos/std/stdarg.d index 9d31ab5e..2f425df4 100644 --- a/lphobos/std/stdarg.d +++ b/lphobos/std/stdarg.d @@ -12,7 +12,8 @@ alias void* va_list; 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; } diff --git a/test/vararg4.d b/test/vararg4.d new file mode 100644 index 00000000..910bc998 --- /dev/null +++ b/test/vararg4.d @@ -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); +}