csret functions can be varargs (as can target cc's). Verify restrictions on
authorChris Lattner <sabre@nondot.org>
Fri, 19 May 2006 21:25:17 +0000 (21:25 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 19 May 2006 21:25:17 +0000 (21:25 +0000)
csret functions.

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

lib/VMCore/Verifier.cpp

index 0814f69d01d1185e47c4dfea255c240dc8355eae..8a4cf2c0d5b73a683faba35dd47c7a327bff793f 100644 (file)
@@ -302,9 +302,6 @@ void Verifier::verifySymbolTable(SymbolTable &ST) {
 // visitFunction - Verify that a function is ok.
 //
 void Verifier::visitFunction(Function &F) {
-  Assert1(!F.isVarArg() || F.getCallingConv() == CallingConv::C,
-          "Varargs functions must have C calling conventions!", &F);
-
   // Check function arguments.
   const FunctionType *FT = F.getFunctionType();
   unsigned NumArgs = F.getArgumentList().size();
@@ -316,6 +313,24 @@ void Verifier::visitFunction(Function &F) {
           F.getReturnType() == Type::VoidTy,
           "Functions cannot return aggregate values!", &F);
 
+  // Check that this function meets the restrictions on this calling convention.
+  switch (F.getCallingConv()) {
+  default:
+    break;
+  case CallingConv::C:
+    break;
+  case CallingConv::CSRet:
+    Assert1(FT->getReturnType() == Type::VoidTy && 
+            FT->getNumParams() > 0 && isa<PointerType>(FT->getParamType(0)),
+            "Invalid struct-return function!", &F);
+    break;
+  case CallingConv::Fast:
+  case CallingConv::Cold:
+    Assert1(!F.isVarArg(),
+            "Varargs functions must have C calling conventions!", &F);
+    break;
+  }
+  
   // Check that the argument values match the function type for this function...
   unsigned i = 0;
   for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I, ++i) {