Enforce that multiple return values have to have at least one result.
authorChris Lattner <sabre@nondot.org>
Wed, 23 Apr 2008 05:36:34 +0000 (05:36 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 23 Apr 2008 05:36:34 +0000 (05:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50137 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DerivedTypes.h
lib/VMCore/Instructions.cpp
lib/VMCore/Type.cpp

index 3ea2a6cb946cf600a85df56ffd5a60a8d068cbe7..533414049fd251c48ccd53097f6ecfe6850aa568 100644 (file)
@@ -154,6 +154,10 @@ public:
     const std::vector<const Type*> &Params, ///< The types of the parameters
     bool isVarArg  ///< Whether this is a variable argument length function
   );
+  
+  /// isValidReturnType - Return true if the specified type is valid as a return
+  /// type.
+  static bool isValidReturnType(const Type *RetTy);
 
   inline bool isVarArg() const { return isVarArgs; }
   inline const Type *getReturnType() const { return ContainedTys[0]; }
index ad99c78c1ab97c904be5b65197af0a6466f43325..56bc8167c3c54d8d97386df13109169ecc717d67 100644 (file)
@@ -2691,7 +2691,7 @@ bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) {
 
   if (const StructType *STy = dyn_cast<StructType>(Aggregate->getType())) {
     unsigned NumElements = STy->getNumElements();
-    if (Index >= NumElements)
+    if (Index >= NumElements || NumElements == 0)
       return false;
 
     // getresult aggregate value's element types are restricted to
index 829923e15a176d2b25a863df06e040c6699cddb1..633991299b2cd6edb3370a930a1e8044cf41ea37 100644 (file)
@@ -437,16 +437,35 @@ const IntegerType *Type::Int64Ty = new BuiltinIntegerType(64);
 //                          Derived Type Constructors
 //===----------------------------------------------------------------------===//
 
+/// isValidReturnType - Return true if the specified type is valid as a return
+/// type.
+bool FunctionType::isValidReturnType(const Type *RetTy) {
+  if (RetTy->isFirstClassType())
+    return true;
+  if (RetTy == Type::VoidTy || isa<OpaqueType>(RetTy))
+    return true;
+  
+  // If this is a multiple return case, verify that each return is a first class
+  // value and that there is at least one value.
+  const StructType *SRetTy = dyn_cast<StructType>(RetTy);
+  if (SRetTy == 0 || SRetTy->getNumElements() == 0)
+    return false;
+  
+  for (unsigned i = 0, e = SRetTy->getNumElements(); i != e; ++i)
+    if (!SRetTy->getElementType(i)->isFirstClassType())
+      return false;
+  return true;
+}
+
 FunctionType::FunctionType(const Type *Result,
                            const std::vector<const Type*> &Params,
                            bool IsVarArgs)
   : DerivedType(FunctionTyID), isVarArgs(IsVarArgs) {
   ContainedTys = reinterpret_cast<PATypeHandle*>(this+1);
   NumContainedTys = Params.size() + 1; // + 1 for result type
-  assert((Result->isFirstClassType() || Result == Type::VoidTy ||
-          Result->getTypeID() == Type::StructTyID ||
-          isa<OpaqueType>(Result)) &&
-         "LLVM functions cannot return aggregates");
+  assert(isValidReturnType(Result) && "invalid return type for function");
+    
+    
   bool isAbstract = Result->isAbstract();
   new (&ContainedTys[0]) PATypeHandle(Result, this);
 
@@ -1091,9 +1110,8 @@ FunctionType *FunctionType::get(const Type *ReturnType,
                                 bool isVarArg) {
   FunctionValType VT(ReturnType, Params, isVarArg);
   FunctionType *FT = FunctionTypes->get(VT);
-  if (FT) { 
+  if (FT)
     return FT;
-  }
 
   FT = (FunctionType*) new char[sizeof(FunctionType) + 
                                 sizeof(PATypeHandle)*(Params.size()+1)];