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); +}