aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/DerivedTypes.h4
-rw-r--r--lib/VMCore/Instructions.cpp2
-rw-r--r--lib/VMCore/Type.cpp30
3 files changed, 29 insertions, 7 deletions
diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h
index 3ea2a6cb94..533414049f 100644
--- a/include/llvm/DerivedTypes.h
+++ b/include/llvm/DerivedTypes.h
@@ -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]; }
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index ad99c78c1a..56bc8167c3 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<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
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index 829923e15a..633991299b 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<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)];