From 7723ab3a51b20ebb44aa344381c558a33104b776 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sat, 12 Jan 2008 18:53:07 +0000 Subject: [PATCH] Indirect call with byval parameter requires a cast first. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45911 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/CBackend/CBackend.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index de5bfa24e50..2de608953d5 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -453,9 +453,14 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty, unsigned Idx = 1; for (FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); I != E; ++I) { + const Type *ArgTy = *I; + if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) { + assert(isa(ArgTy)); + ArgTy = cast(ArgTy)->getElementType(); + } if (I != FTy->param_begin()) FunctionInnards << ", "; - printType(FunctionInnards, *I, + printType(FunctionInnards, ArgTy, /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), ""); ++Idx; } @@ -495,6 +500,9 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty, isa(PTy->getElementType())) ptrName = "(" + ptrName + ")"; + if (PAL) + // Must be a function ptr cast! + return printType(Out, PTy->getElementType(), false, ptrName, true, PAL); return printType(Out, PTy->getElementType(), false, ptrName); } @@ -2632,6 +2640,7 @@ void CWriter::visitCallInst(CallInst &I) { // If this is a call to a struct-return function, assign to the first // parameter instead of passing it to the call. const ParamAttrsList *PAL = I.getParamAttrs(); + bool hasByVal = I.hasByValArgument(); bool isStructRet = I.isStructReturn(); if (isStructRet) { bool isByVal = ByValParams.count(I.getOperand(1)); @@ -2645,8 +2654,8 @@ void CWriter::visitCallInst(CallInst &I) { if (!WroteCallee) { // If this is an indirect call to a struct return function, we need to cast - // the pointer. - bool NeedsCast = isStructRet && !isa(Callee); + // the pointer. Ditto for indirect calls with byval arguments. + bool NeedsCast = (hasByVal || isStructRet) && !isa(Callee); // GCC is a real PITA. It does not permit codegening casts of functions to // function pointers if they are in a call (it generates a trap instruction @@ -2670,11 +2679,13 @@ void CWriter::visitCallInst(CallInst &I) { if (NeedsCast) { // Ok, just cast the pointer type. Out << "(("; - if (!isStructRet) - printType(Out, I.getCalledValue()->getType()); - else + if (isStructRet) printStructReturnPointerFunctionType(Out, PAL, cast(I.getCalledValue()->getType())); + else if (hasByVal) + printType(Out, I.getCalledValue()->getType(), false, "", true, PAL); + else + printType(Out, I.getCalledValue()->getType()); Out << ")(void*)"; } writeOperand(Callee);