diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 427975deb1..f16c600e9c 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1864,6 +1864,14 @@ LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) { return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType())); } +static unsigned ClangCallConvToLLVMCallConv(CallingConv CC) { + switch (CC) { + default: return llvm::CallingConv::C; + case CC_X86StdCall: return llvm::CallingConv::X86_StdCall; + case CC_X86FastCall: return llvm::CallingConv::X86_FastCall; + } +} + RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee, ReturnValueSlot ReturnValue, CallExpr::const_arg_iterator ArgBeg, @@ -1882,12 +1890,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee, CallArgList Args; EmitCallArgs(Args, dyn_cast(FnType), ArgBeg, ArgEnd); - // FIXME: We should not need to do this, it should be part of the function - // type. - unsigned CallingConvention = 0; - if (const llvm::Function *F = - dyn_cast(Callee->stripPointerCasts())) - CallingConvention = F->getCallingConv(); + unsigned CallingConvention = + ClangCallConvToLLVMCallConv(FnType->getAs()->getCallConv()); return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args, CallingConvention), Callee, ReturnValue, Args, TargetDecl); diff --git a/test/CodeGen/stdcall-fastcall.c b/test/CodeGen/stdcall-fastcall.c index 838ccfb48c..1fbed300d8 100644 --- a/test/CodeGen/stdcall-fastcall.c +++ b/test/CodeGen/stdcall-fastcall.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -emit-llvm < %s | grep 'fastcallcc' | count 4 -// RUN: %clang_cc1 -emit-llvm < %s | grep 'stdcallcc' | count 4 +// RUN: %clang_cc1 -emit-llvm < %s | grep 'fastcallcc' | count 6 +// RUN: %clang_cc1 -emit-llvm < %s | grep 'stdcallcc' | count 6 void __attribute__((fastcall)) f1(void); void __attribute__((stdcall)) f2(void); @@ -10,8 +10,15 @@ void __attribute__((stdcall)) f4(void) { f2(); } +// PR5280 +void (__attribute__((fastcall)) *pf1)(void) = f1; +void (__attribute__((stdcall)) *pf2)(void) = f2; +void (__attribute__((fastcall)) *pf3)(void) = f3; +void (__attribute__((stdcall)) *pf4)(void) = f4; + int main(void) { f3(); f4(); + pf1(); pf2(); pf3(); pf4(); return 0; }