fix a fixme: non-proto struct returning function definitions should be compiled
authorChris Lattner <sabre@nondot.org>
Sun, 22 Mar 2009 19:35:37 +0000 (19:35 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 22 Mar 2009 19:35:37 +0000 (19:35 +0000)
to something like:
define void @bar(%struct.foo* noalias sret %agg.result) nounwind {
instead of:
define void @bar(%struct.foo* noalias sret %agg.result, ...) nounwind {

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67475 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
test/CodeGen/functions.c

index 4cd046d74edeb7f77b983e6954ddedb1b1db330a..6f745f2b90c6d9899a6fc7d3bccafd6f4154ba96 100644 (file)
@@ -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<const llvm::Type*>(), 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<const llvm::Type*> 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);
index ad918263c5fdb07a81ecff9747e5d40dbf74cb66..3b50df79f6deae873280e86941d9c2d76ac5179a 100644 (file)
@@ -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() {
+}