From c1d848dd11f9ce3fb5956673652430d895891b6a Mon Sep 17 00:00:00 2001
From: Anton Korobeynikov <asl@math.spbu.ru>
Date: Mon, 3 Dec 2007 19:16:54 +0000
Subject: [PATCH] More sanity checks for function types. Thanks goes to PyPy
 folks for generating broken stuff :)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44538 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/AsmParser/llvmAsmParser.y     | 14 +++++++++++++-
 lib/AsmParser/llvmAsmParser.y.cvs | 14 +++++++++++++-
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index 31fd6190827..ae6da07893f 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -1330,16 +1330,24 @@ Types
   | Types '(' ArgTypeListI ')' OptFuncAttrs {
     // Allow but ignore attributes on function types; this permits auto-upgrade.
     // FIXME: remove in LLVM 3.0.
+    const Type* RetTy = *$1;
+    if (!(RetTy->isFirstClassType() || isa<OpaqueType>(RetTy)))
+      GEN_ERROR("LLVM Functions cannot return aggregates");
+
     std::vector<const Type*> Params;
     TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
     for (; I != E; ++I ) {
       const Type *Ty = I->Ty->get();
+      if (!(Ty->isFirstClassType() || isa<OpaqueType>(Ty)))
+        GEN_ERROR("Function arguments must be value types!");
       Params.push_back(Ty);
     }
+    CHECK_FOR_ERROR
+
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
-    FunctionType *FT = FunctionType::get(*$1, Params, isVarArg);
+    FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg);
     delete $3;   // Delete the argument list
     delete $1;   // Delete the return type handle
     $$ = new PATypeHolder(HandleUpRefs(FT)); 
@@ -1352,8 +1360,12 @@ Types
     TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
     for ( ; I != E; ++I ) {
       const Type* Ty = I->Ty->get();
+      if (!(Ty->isFirstClassType() || isa<OpaqueType>(Ty)))
+        GEN_ERROR("Function arguments must be value types!");
       Params.push_back(Ty);
     }
+    CHECK_FOR_ERROR
+
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
diff --git a/lib/AsmParser/llvmAsmParser.y.cvs b/lib/AsmParser/llvmAsmParser.y.cvs
index 31fd6190827..ae6da07893f 100644
--- a/lib/AsmParser/llvmAsmParser.y.cvs
+++ b/lib/AsmParser/llvmAsmParser.y.cvs
@@ -1330,16 +1330,24 @@ Types
   | Types '(' ArgTypeListI ')' OptFuncAttrs {
     // Allow but ignore attributes on function types; this permits auto-upgrade.
     // FIXME: remove in LLVM 3.0.
+    const Type* RetTy = *$1;
+    if (!(RetTy->isFirstClassType() || isa<OpaqueType>(RetTy)))
+      GEN_ERROR("LLVM Functions cannot return aggregates");
+
     std::vector<const Type*> Params;
     TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
     for (; I != E; ++I ) {
       const Type *Ty = I->Ty->get();
+      if (!(Ty->isFirstClassType() || isa<OpaqueType>(Ty)))
+        GEN_ERROR("Function arguments must be value types!");
       Params.push_back(Ty);
     }
+    CHECK_FOR_ERROR
+
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
-    FunctionType *FT = FunctionType::get(*$1, Params, isVarArg);
+    FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg);
     delete $3;   // Delete the argument list
     delete $1;   // Delete the return type handle
     $$ = new PATypeHolder(HandleUpRefs(FT)); 
@@ -1352,8 +1360,12 @@ Types
     TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
     for ( ; I != E; ++I ) {
       const Type* Ty = I->Ty->get();
+      if (!(Ty->isFirstClassType() || isa<OpaqueType>(Ty)))
+        GEN_ERROR("Function arguments must be value types!");
       Params.push_back(Ty);
     }
+    CHECK_FOR_ERROR
+
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();