diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 4cd046d74ede..6f745f2b90c6 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -859,10 +859,13 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { // As a special case, make sure that definitions of K&R function // "type foo()" aren't declared as varargs (which forces the backend // to do unnecessary work). - // FIXME: what about stret() functions, this doesn't handle them!? - if (Ty->isVarArg() && Ty->getNumParams() == 0) - Ty = llvm::FunctionType::get(Ty->getReturnType(), - std::vector(), false); + if (D->getType()->isFunctionNoProtoType()) { + assert(Ty->isVarArg() && "Didn't lower type as expected"); + // Due to stret, the lowered function could have arguments. Just create the + // same type as was lowered by ConvertType but strip off the varargs bit. + std::vector Args(Ty->param_begin(), Ty->param_end()); + Ty = llvm::FunctionType::get(Ty->getReturnType(), Args, false); + } // Get or create the prototype for teh function. llvm::Constant *Entry = GetAddrOfFunction(D, Ty); diff --git a/clang/test/CodeGen/functions.c b/clang/test/CodeGen/functions.c index ad918263c5fd..3b50df79f6de 100644 --- a/clang/test/CodeGen/functions.c +++ b/clang/test/CodeGen/functions.c @@ -27,5 +27,9 @@ void f1(); void f2(void) { f1(1, 2, 3); } -// RUN: grep 'define void @f1()' %t +// RUN: grep 'define void @f1()' %t && void f1() {} + +// RUN: grep 'define .* @f3' %t | not grep -F '...' +struct foo { int X, Y, Z; } f3() { +}