diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index 3ea2a6cb946..533414049fd 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -154,6 +154,10 @@ public: const std::vector &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]; } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index ad99c78c1ab..56bc8167c3c 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -2691,7 +2691,7 @@ bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) { if (const StructType *STy = dyn_cast(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 diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index 829923e15a1..633991299b2 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -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(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(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 &Params, bool IsVarArgs) : DerivedType(FunctionTyID), isVarArgs(IsVarArgs) { ContainedTys = reinterpret_cast(this+1); NumContainedTys = Params.size() + 1; // + 1 for result type - assert((Result->isFirstClassType() || Result == Type::VoidTy || - Result->getTypeID() == Type::StructTyID || - isa(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)];