diff --git a/gen/abi-x86-64.cpp b/gen/abi-x86-64.cpp index 910cd033..6f16ab04 100644 --- a/gen/abi-x86-64.cpp +++ b/gen/abi-x86-64.cpp @@ -428,7 +428,8 @@ bool X86_64TargetABI::returnInArg(TypeFunction* tf) { bool X86_64TargetABI::passByVal(Type* t) { t = t->toBasetype(); if (linkage() == LINKd) { - return t->toBasetype()->ty == Tstruct; + // static arrays are also passed byval + return t->ty == Tstruct || t->ty == Tsarray; } else { // This implements the C calling convention for x86-64. // It might not be correct for other calling conventions. @@ -598,6 +599,11 @@ void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) { else { Logger::println("Putting static array in register"); + // need to make sure type is not pointer + arg.ltype = DtoType(arg.type); + arg.byref = false; + // erase previous attributes + arg.attrs = 0; } arg.attrs |= llvm::Attribute::InReg; --regcount; diff --git a/gen/abi.cpp b/gen/abi.cpp index 0ec72e7f..21cad4f6 100644 --- a/gen/abi.cpp +++ b/gen/abi.cpp @@ -108,7 +108,7 @@ struct X86TargetABI : TargetABI bool passByVal(Type* t) { - return t->toBasetype()->ty == Tstruct; + return t->toBasetype()->ty == Tstruct || t->toBasetype()->ty == Tsarray; } void rewriteFunctionType(TypeFunction* tf) diff --git a/gen/functions.cpp b/gen/functions.cpp index d7946fa8..19a627d6 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -162,6 +162,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, else if (abi->passByVal(byref ? argtype->pointerTo() : argtype)) { if (!byref) a |= llvm::Attribute::ByVal; + // set byref, because byval requires a pointed LLVM type byref = true; } // sext/zext diff --git a/ir/irfunction.cpp b/ir/irfunction.cpp index d9b4e5fd..8a391435 100644 --- a/ir/irfunction.cpp +++ b/ir/irfunction.cpp @@ -13,9 +13,8 @@ ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -IrFuncTyArg::IrFuncTyArg(Type* t, bool bref, unsigned a) +IrFuncTyArg::IrFuncTyArg(Type* t, bool bref, unsigned a) : type(t) { - type = t; ltype = t != Type::tvoid && bref ? DtoType(t->pointerTo()) : DtoType(t); attrs = a; byref = bref; diff --git a/ir/irfuncty.h b/ir/irfuncty.h index 00623cad..34aa28b0 100644 --- a/ir/irfuncty.h +++ b/ir/irfuncty.h @@ -20,7 +20,7 @@ struct IrFuncTyArg : IrBase { /** This is the original D type as the frontend knows it * May NOT be rewritten!!! */ - Type* type; + Type* const type; /// This is the final LLVM Type used for the parameter/return value type llvm::Type* ltype; @@ -92,7 +92,7 @@ struct IrFuncTy : IrBase {} #if defined(_MSC_VER) - // Copy constructor and operator= seems to be requreid for MSC + // Copy constructor and operator= seems to be required for MSC IrFuncTy(const IrFuncTy& rhs) : ret(rhs.ret),