diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-11-04 16:16:24 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-11-04 16:16:24 +0000 |
commit | e076b5338a8a004b4ea3694c469760d87194a5d7 (patch) | |
tree | 180bd12204cba93deeed15bc3715749bd554b611 | |
parent | 5c042162beb3c2dd556e00aab84c4278a69cd5b1 (diff) | |
download | external_llvm-e076b5338a8a004b4ea3694c469760d87194a5d7.zip external_llvm-e076b5338a8a004b4ea3694c469760d87194a5d7.tar.gz external_llvm-e076b5338a8a004b4ea3694c469760d87194a5d7.tar.bz2 |
Change BitcodeReader to use error_code instead of bool + string.
In order to create an ObjectFile implementation that uses bitcode files, we
need to propagate the bitcode errors to the ObjectFile interface, so we need
to convert it to use the same error handling as ObjectFile: error_code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193996 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 786 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.h | 86 | ||||
-rw-r--r-- | test/Bitcode/invalid.ll | 2 | ||||
-rw-r--r-- | test/Bitcode/null-type.ll | 2 |
4 files changed, 495 insertions, 381 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 2a2f96c..d571fd8 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -450,12 +450,12 @@ static void decodeLLVMAttributesForBitcode(AttrBuilder &B, (EncodedAttrs & 0xffff)); } -bool BitcodeReader::ParseAttributeBlock() { +error_code BitcodeReader::ParseAttributeBlock() { if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) - return Error("Malformed block record"); + return Error(InvalidRecord); if (!MAttributes.empty()) - return Error("Multiple PARAMATTR blocks found!"); + return Error(InvalidMultipleBlocks); SmallVector<uint64_t, 64> Record; @@ -468,9 +468,9 @@ bool BitcodeReader::ParseAttributeBlock() { switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: - return Error("Error at end of PARAMATTR block"); + return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return false; + return error_code::success(); case BitstreamEntry::Record: // The interesting case. break; @@ -484,7 +484,7 @@ bool BitcodeReader::ParseAttributeBlock() { case bitc::PARAMATTR_CODE_ENTRY_OLD: { // ENTRY: [paramidx0, attr0, ...] // FIXME: Remove in 4.0. if (Record.size() & 1) - return Error("Invalid ENTRY record"); + return Error(InvalidRecord); for (unsigned i = 0, e = Record.size(); i != e; i += 2) { AttrBuilder B; @@ -508,130 +508,131 @@ bool BitcodeReader::ParseAttributeBlock() { } } -bool BitcodeReader::ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind) { +error_code BitcodeReader::ParseAttrKind(uint64_t Code, + Attribute::AttrKind *Kind) { switch (Code) { case bitc::ATTR_KIND_ALIGNMENT: *Kind = Attribute::Alignment; - return false; + return error_code::success(); case bitc::ATTR_KIND_ALWAYS_INLINE: *Kind = Attribute::AlwaysInline; - return false; + return error_code::success(); case bitc::ATTR_KIND_BUILTIN: *Kind = Attribute::Builtin; - return false; + return error_code::success(); case bitc::ATTR_KIND_BY_VAL: *Kind = Attribute::ByVal; - return false; + return error_code::success(); case bitc::ATTR_KIND_COLD: *Kind = Attribute::Cold; - return false; + return error_code::success(); case bitc::ATTR_KIND_INLINE_HINT: *Kind = Attribute::InlineHint; - return false; + return error_code::success(); case bitc::ATTR_KIND_IN_REG: *Kind = Attribute::InReg; - return false; + return error_code::success(); case bitc::ATTR_KIND_MIN_SIZE: *Kind = Attribute::MinSize; - return false; + return error_code::success(); case bitc::ATTR_KIND_NAKED: *Kind = Attribute::Naked; - return false; + return error_code::success(); case bitc::ATTR_KIND_NEST: *Kind = Attribute::Nest; - return false; + return error_code::success(); case bitc::ATTR_KIND_NO_ALIAS: *Kind = Attribute::NoAlias; - return false; + return error_code::success(); case bitc::ATTR_KIND_NO_BUILTIN: *Kind = Attribute::NoBuiltin; - return false; + return error_code::success(); case bitc::ATTR_KIND_NO_CAPTURE: *Kind = Attribute::NoCapture; - return false; + return error_code::success(); case bitc::ATTR_KIND_NO_DUPLICATE: *Kind = Attribute::NoDuplicate; - return false; + return error_code::success(); case bitc::ATTR_KIND_NO_IMPLICIT_FLOAT: *Kind = Attribute::NoImplicitFloat; - return false; + return error_code::success(); case bitc::ATTR_KIND_NO_INLINE: *Kind = Attribute::NoInline; - return false; + return error_code::success(); case bitc::ATTR_KIND_NON_LAZY_BIND: *Kind = Attribute::NonLazyBind; - return false; + return error_code::success(); case bitc::ATTR_KIND_NO_RED_ZONE: *Kind = Attribute::NoRedZone; - return false; + return error_code::success(); case bitc::ATTR_KIND_NO_RETURN: *Kind = Attribute::NoReturn; - return false; + return error_code::success(); case bitc::ATTR_KIND_NO_UNWIND: *Kind = Attribute::NoUnwind; - return false; + return error_code::success(); case bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE: *Kind = Attribute::OptimizeForSize; - return false; + return error_code::success(); case bitc::ATTR_KIND_OPTIMIZE_NONE: *Kind = Attribute::OptimizeNone; - return false; + return error_code::success(); case bitc::ATTR_KIND_READ_NONE: *Kind = Attribute::ReadNone; - return false; + return error_code::success(); case bitc::ATTR_KIND_READ_ONLY: *Kind = Attribute::ReadOnly; - return false; + return error_code::success(); case bitc::ATTR_KIND_RETURNED: *Kind = Attribute::Returned; - return false; + return error_code::success(); case bitc::ATTR_KIND_RETURNS_TWICE: *Kind = Attribute::ReturnsTwice; - return false; + return error_code::success(); case bitc::ATTR_KIND_S_EXT: *Kind = Attribute::SExt; - return false; + return error_code::success(); case bitc::ATTR_KIND_STACK_ALIGNMENT: *Kind = Attribute::StackAlignment; - return false; + return error_code::success(); case bitc::ATTR_KIND_STACK_PROTECT: *Kind = Attribute::StackProtect; - return false; + return error_code::success(); case bitc::ATTR_KIND_STACK_PROTECT_REQ: *Kind = Attribute::StackProtectReq; - return false; + return error_code::success(); case bitc::ATTR_KIND_STACK_PROTECT_STRONG: *Kind = Attribute::StackProtectStrong; - return false; + return error_code::success(); case bitc::ATTR_KIND_STRUCT_RET: *Kind = Attribute::StructRet; - return false; + return error_code::success(); case bitc::ATTR_KIND_SANITIZE_ADDRESS: *Kind = Attribute::SanitizeAddress; - return false; + return error_code::success(); case bitc::ATTR_KIND_SANITIZE_THREAD: *Kind = Attribute::SanitizeThread; - return false; + return error_code::success(); case bitc::ATTR_KIND_SANITIZE_MEMORY: *Kind = Attribute::SanitizeMemory; - return false; + return error_code::success(); case bitc::ATTR_KIND_UW_TABLE: *Kind = Attribute::UWTable; - return false; + return error_code::success(); case bitc::ATTR_KIND_Z_EXT: *Kind = Attribute::ZExt; - return false; + return error_code::success(); default: - return Error("Unknown attribute kind"); + return Error(InvalidValue); } } -bool BitcodeReader::ParseAttributeGroupBlock() { +error_code BitcodeReader::ParseAttributeGroupBlock() { if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) - return Error("Malformed block record"); + return Error(InvalidRecord); if (!MAttributeGroups.empty()) - return Error("Multiple PARAMATTR_GROUP blocks found!"); + return Error(InvalidMultipleBlocks); SmallVector<uint64_t, 64> Record; @@ -642,9 +643,9 @@ bool BitcodeReader::ParseAttributeGroupBlock() { switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: - return Error("Error at end of PARAMATTR_GROUP block"); + return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return false; + return error_code::success(); case BitstreamEntry::Record: // The interesting case. break; @@ -657,7 +658,7 @@ bool BitcodeReader::ParseAttributeGroupBlock() { break; case bitc::PARAMATTR_GRP_CODE_ENTRY: { // ENTRY: [grpid, idx, a0, a1, ...] if (Record.size() < 3) - return Error("Invalid ENTRY record"); + return Error(InvalidRecord); uint64_t GrpID = Record[0]; uint64_t Idx = Record[1]; // Index of the object this attribute refers to. @@ -666,14 +667,14 @@ bool BitcodeReader::ParseAttributeGroupBlock() { for (unsigned i = 2, e = Record.size(); i != e; ++i) { if (Record[i] == 0) { // Enum attribute Attribute::AttrKind Kind; - if (ParseAttrKind(Record[++i], &Kind)) - return true; + if (error_code EC = ParseAttrKind(Record[++i], &Kind)) + return EC; B.addAttribute(Kind); } else if (Record[i] == 1) { // Align attribute Attribute::AttrKind Kind; - if (ParseAttrKind(Record[++i], &Kind)) - return true; + if (error_code EC = ParseAttrKind(Record[++i], &Kind)) + return EC; if (Kind == Attribute::Alignment) B.addAlignmentAttr(Record[++i]); else @@ -708,16 +709,16 @@ bool BitcodeReader::ParseAttributeGroupBlock() { } } -bool BitcodeReader::ParseTypeTable() { +error_code BitcodeReader::ParseTypeTable() { if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) - return Error("Malformed block record"); + return Error(InvalidRecord); return ParseTypeTableBody(); } -bool BitcodeReader::ParseTypeTableBody() { +error_code BitcodeReader::ParseTypeTableBody() { if (!TypeList.empty()) - return Error("Multiple TYPE_BLOCKs found!"); + return Error(InvalidMultipleBlocks); SmallVector<uint64_t, 64> Record; unsigned NumRecords = 0; @@ -731,12 +732,11 @@ bool BitcodeReader::ParseTypeTableBody() { switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: - Error("Error in the type table block"); - return true; + return Error(MalformedBlock); case BitstreamEntry::EndBlock: if (NumRecords != TypeList.size()) - return Error("Invalid type forward reference in TYPE_BLOCK"); - return false; + return Error(MalformedBlock); + return error_code::success(); case BitstreamEntry::Record: // The interesting case. break; @@ -746,12 +746,13 @@ bool BitcodeReader::ParseTypeTableBody() { Record.clear(); Type *ResultTy = 0; switch (Stream.readRecord(Entry.ID, Record)) { - default: return Error("unknown type in type table"); + default: + return Error(InvalidValue); case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries] // TYPE_CODE_NUMENTRY contains a count of the number of types in the // type list. This allows us to reserve space. if (Record.size() < 1) - return Error("Invalid TYPE_CODE_NUMENTRY record"); + return Error(InvalidRecord); TypeList.resize(Record[0]); continue; case bitc::TYPE_CODE_VOID: // VOID @@ -786,19 +787,20 @@ bool BitcodeReader::ParseTypeTableBody() { break; case bitc::TYPE_CODE_INTEGER: // INTEGER: [width] if (Record.size() < 1) - return Error("Invalid Integer type record"); + return Error(InvalidRecord); ResultTy = IntegerType::get(Context, Record[0]); break; case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or // [pointee type, address space] if (Record.size() < 1) - return Error("Invalid POINTER type record"); + return Error(InvalidRecord); unsigned AddressSpace = 0; if (Record.size() == 2) AddressSpace = Record[1]; ResultTy = getTypeByID(Record[0]); - if (ResultTy == 0) return Error("invalid element type in pointer type"); + if (ResultTy == 0) + return Error(InvalidType); ResultTy = PointerType::get(ResultTy, AddressSpace); break; } @@ -806,7 +808,7 @@ bool BitcodeReader::ParseTypeTableBody() { // FIXME: attrid is dead, remove it in LLVM 4.0 // FUNCTION: [vararg, attrid, retty, paramty x N] if (Record.size() < 3) - return Error("Invalid FUNCTION type record"); + return Error(InvalidRecord); SmallVector<Type*, 8> ArgTys; for (unsigned i = 3, e = Record.size(); i != e; ++i) { if (Type *T = getTypeByID(Record[i])) @@ -817,7 +819,7 @@ bool BitcodeReader::ParseTypeTableBody() { ResultTy = getTypeByID(Record[2]); if (ResultTy == 0 || ArgTys.size() < Record.size()-3) - return Error("invalid type in function type"); + return Error(InvalidType); ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]); break; @@ -825,7 +827,7 @@ bool BitcodeReader::ParseTypeTableBody() { case bitc::TYPE_CODE_FUNCTION: { // FUNCTION: [vararg, retty, paramty x N] if (Record.size() < 2) - return Error("Invalid FUNCTION type record"); + return Error(InvalidRecord); SmallVector<Type*, 8> ArgTys; for (unsigned i = 2, e = Record.size(); i != e; ++i) { if (Type *T = getTypeByID(Record[i])) @@ -836,14 +838,14 @@ bool BitcodeReader::ParseTypeTableBody() { ResultTy = getTypeByID(Record[1]); if (ResultTy == 0 || ArgTys.size() < Record.size()-2) - return Error("invalid type in function type"); + return Error(InvalidType); ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]); break; } case bitc::TYPE_CODE_STRUCT_ANON: { // STRUCT: [ispacked, eltty x N] if (Record.size() < 1) - return Error("Invalid STRUCT type record"); + return Error(InvalidRecord); SmallVector<Type*, 8> EltTys; for (unsigned i = 1, e = Record.size(); i != e; ++i) { if (Type *T = getTypeByID(Record[i])) @@ -852,21 +854,21 @@ bool BitcodeReader::ParseTypeTableBody() { break; } if (EltTys.size() != Record.size()-1) - return Error("invalid type in struct type"); + return Error(InvalidType); ResultTy = StructType::get(Context, EltTys, Record[0]); break; } case bitc::TYPE_CODE_STRUCT_NAME: // STRUCT_NAME: [strchr x N] if (ConvertToString(Record, 0, TypeName)) - return Error("Invalid STRUCT_NAME record"); + return Error(InvalidRecord); continue; case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N] if (Record.size() < 1) - return Error("Invalid STRUCT type record"); + return Error(InvalidRecord); if (NumRecords >= TypeList.size()) - return Error("invalid TYPE table"); + return Error(InvalidTYPETable); // Check to see if this was forward referenced, if so fill in the temp. StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]); @@ -885,17 +887,17 @@ bool BitcodeReader::ParseTypeTableBody() { break; } if (EltTys.size() != Record.size()-1) - return Error("invalid STRUCT type record"); + return Error(InvalidRecord); Res->setBody(EltTys, Record[0]); ResultTy = Res; break; } case bitc::TYPE_CODE_OPAQUE: { // OPAQUE: [] if (Record.size() != 1) - return Error("Invalid OPAQUE type record"); + return Error(InvalidRecord); if (NumRecords >= TypeList.size()) - return Error("invalid TYPE table"); + return Error(InvalidTYPETable); // Check to see if this was forward referenced, if so fill in the temp. StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]); @@ -910,33 +912,33 @@ bool BitcodeReader::ParseTypeTableBody() { } case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty] if (Record.size() < 2) - return Error("Invalid ARRAY type record"); + return Error(InvalidRecord); if ((ResultTy = getTypeByID(Record[1]))) ResultTy = ArrayType::get(ResultTy, Record[0]); else - return Error("Invalid ARRAY type element"); + return Error(InvalidType); break; case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] if (Record.size() < 2) - return Error("Invalid VECTOR type record"); + return Error(InvalidRecord); if ((ResultTy = getTypeByID(Record[1]))) ResultTy = VectorType::get(ResultTy, Record[0]); else - return Error("Invalid ARRAY type element"); + return Error(InvalidType); break; } if (NumRecords >= TypeList.size()) - return Error("invalid TYPE table"); + return Error(InvalidTYPETable); assert(ResultTy && "Didn't read a type?"); assert(TypeList[NumRecords] == 0 && "Already read type?"); TypeList[NumRecords++] = ResultTy; } } -bool BitcodeReader::ParseValueSymbolTable() { +error_code BitcodeReader::ParseValueSymbolTable() { if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) - return Error("Malformed block record"); + return Error(InvalidRecord); SmallVector<uint64_t, 64> Record; @@ -948,9 +950,9 @@ bool BitcodeReader::ParseValueSymbolTable() { switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: - return Error("malformed value symbol table block"); + return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return false; + return error_code::success(); case BitstreamEntry::Record: // The interesting case. break; @@ -963,10 +965,10 @@ bool BitcodeReader::ParseValueSymbolTable() { break; case bitc::VST_CODE_ENTRY: { // VST_ENTRY: [valueid, namechar x N] if (ConvertToString(Record, 1, ValueName)) - return Error("Invalid VST_ENTRY record"); + return Error(InvalidRecord); unsigned ValueID = Record[0]; if (ValueID >= ValueList.size()) - return Error("Invalid Value ID in VST_ENTRY record"); + return Error(InvalidRecord); Value *V = ValueList[ValueID]; V->setName(StringRef(ValueName.data(), ValueName.size())); @@ -975,10 +977,10 @@ bool BitcodeReader::ParseValueSymbolTable() { } case bitc::VST_CODE_BBENTRY: { if (ConvertToString(Record, 1, ValueName)) - return Error("Invalid VST_BBENTRY record"); + return Error(InvalidRecord); BasicBlock *BB = getBasicBlock(Record[0]); if (BB == 0) - return Error("Invalid BB ID in VST_BBENTRY record"); + return Error(InvalidRecord); BB->setName(StringRef(ValueName.data(), ValueName.size())); ValueName.clear(); @@ -988,11 +990,11 @@ bool BitcodeReader::ParseValueSymbolTable() { } } -bool BitcodeReader::ParseMetadata() { +error_code BitcodeReader::ParseMetadata() { unsigned NextMDValueNo = MDValueList.size(); if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID)) - return Error("Malformed block record"); + return Error(InvalidRecord); SmallVector<uint64_t, 64> Record; @@ -1003,10 +1005,9 @@ bool BitcodeReader::ParseMetadata() { switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: - Error("malformed metadata block"); - return true; + return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return false; + return error_code::success(); case BitstreamEntry::Record: // The interesting case. break; @@ -1035,7 +1036,7 @@ bool BitcodeReader::ParseMetadata() { for (unsigned i = 0; i != Size; ++i) { MDNode *MD = dyn_cast<MDNode>(MDValueList.getValueFwdRef(Record[i])); if (MD == 0) - return Error("Malformed metadata record"); + return Error(InvalidRecord); NMD->addOperand(MD); } break; @@ -1045,13 +1046,14 @@ bool BitcodeReader::ParseMetadata() { // fall-through case bitc::METADATA_NODE: { if (Record.size() % 2 == 1) - return Error("Invalid METADATA_NODE record"); + return Error(InvalidRecord); unsigned Size = Record.size(); SmallVector<Value*, 8> Elts; for (unsigned i = 0; i != Size; i += 2) { Type *Ty = getTypeByID(Record[i]); - if (!Ty) return Error("Invalid METADATA_NODE record"); + if (!Ty) + return Error(InvalidRecord); if (Ty->isMetadataTy()) Elts.push_back(MDValueList.getValueFwdRef(Record[i+1])); else if (!Ty->isVoidTy()) @@ -1072,14 +1074,14 @@ bool BitcodeReader::ParseMetadata() { } case bitc::METADATA_KIND: { if (Record.size() < 2) - return Error("Invalid METADATA_KIND record"); + return Error(InvalidRecord); unsigned Kind = Record[0]; SmallString<8> Name(Record.begin()+1, Record.end()); unsigned NewKind = TheModule->getMDKindID(Name.str()); if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second) - return Error("Conflicting METADATA_KIND records"); + return Error(ConflictingMETADATA_KINDRecords); break; } } @@ -1099,7 +1101,7 @@ uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) { /// ResolveGlobalAndAliasInits - Resolve all of the initializers for global /// values and aliases that we can. -bool BitcodeReader::ResolveGlobalAndAliasInits() { +error_code BitcodeReader::ResolveGlobalAndAliasInits() { std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist; std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist; std::vector<std::pair<Function*, unsigned> > FunctionPrefixWorklist; @@ -1117,7 +1119,7 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() { if (Constant *C = dyn_cast<Constant>(ValueList[ValID])) GlobalInitWorklist.back().first->setInitializer(C); else - return Error("Global variable initializer is not a constant!"); + return Error(ExpectedConstant); } GlobalInitWorklist.pop_back(); } @@ -1130,7 +1132,7 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() { if (Constant *C = dyn_cast<Constant>(ValueList[ValID])) AliasInitWorklist.back().first->setAliasee(C); else - return Error("Alias initializer is not a constant!"); + return Error(ExpectedConstant); } AliasInitWorklist.pop_back(); } @@ -1143,12 +1145,12 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() { if (Constant *C = dyn_cast<Constant>(ValueList[ValID])) FunctionPrefixWorklist.back().first->setPrefixData(C); else - return Error("Function prefix is not a constant!"); + return Error(ExpectedConstant); } FunctionPrefixWorklist.pop_back(); } - return false; + return error_code::success(); } static APInt ReadWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) { @@ -1159,9 +1161,9 @@ static APInt ReadWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) { return APInt(TypeBits, Words); } -bool BitcodeReader::ParseConstants() { +error_code BitcodeReader::ParseConstants() { if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID)) - return Error("Malformed block record"); + return Error(InvalidRecord); SmallVector<uint64_t, 64> Record; @@ -1174,15 +1176,15 @@ bool BitcodeReader::ParseConstants() { switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: - return Error("malformed block record in AST file"); + return Error(MalformedBlock); case BitstreamEntry::EndBlock: if (NextCstNo != ValueList.size()) - return Error("Invalid constant reference!"); + return Error(InvalidConstantReference); // Once all the constants have been read, go through and resolve forward // references. ValueList.ResolveConstantForwardRefs(); - return false; + return error_code::success(); case BitstreamEntry::Record: // The interesting case. break; @@ -1199,9 +1201,9 @@ bool BitcodeReader::ParseConstants() { break; case bitc::CST_CODE_SETTYPE: // SETTYPE: [typeid] if (Record.empty()) - return Error("Malformed CST_SETTYPE record"); + return Error(InvalidRecord); if (Record[0] >= TypeList.size()) - return Error("Invalid Type ID in CST_SETTYPE record"); + return Error(InvalidRecord); CurTy = TypeList[Record[0]]; continue; // Skip the ValueList manipulation. case bitc::CST_CODE_NULL: // NULL @@ -1209,12 +1211,12 @@ bool BitcodeReader::ParseConstants() { break; case bitc::CST_CODE_INTEGER: // INTEGER: [intval] if (!CurTy->isIntegerTy() || Record.empty()) - return Error("Invalid CST_INTEGER record"); + return Error(InvalidRecord); V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0])); break; case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval] if (!CurTy->isIntegerTy() || Record.empty()) - return Error("Invalid WIDE_INTEGER record"); + return Error(InvalidRecord); APInt VInt = ReadWideAPInt(Record, cast<IntegerType>(CurTy)->getBitWidth()); @@ -1224,7 +1226,7 @@ bool BitcodeReader::ParseConstants() { } case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval] if (Record.empty()) - return Error("Invalid FLOAT record"); + return Error(InvalidRecord); if (CurTy->isHalfTy()) V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf, APInt(16, (uint16_t)Record[0]))); @@ -1254,7 +1256,7 @@ bool BitcodeReader::ParseConstants() { case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n x value number] if (Record.empty()) - return Error("Invalid CST_AGGREGATE record"); + return Error(InvalidRecord); unsigned Size = Record.size(); SmallVector<Constant*, 16> Elts; @@ -1282,7 +1284,7 @@ bool BitcodeReader::ParseConstants() { case bitc::CST_CODE_STRING: // STRING: [values] case bitc::CST_CODE_CSTRING: { // CSTRING: [values] if (Record.empty()) - return Error("Invalid CST_STRING record"); + return Error(InvalidRecord); SmallString<16> Elts(Record.begin(), Record.end()); V = ConstantDataArray::getString(Context, Elts, @@ -1291,7 +1293,7 @@ bool BitcodeReader::ParseConstants() { } case bitc::CST_CODE_DATA: {// DATA: [n x value] if (Record.empty()) - return Error("Invalid CST_DATA record"); + return Error(InvalidRecord); Type *EltTy = cast<SequentialType>(CurTy)->getElementType(); unsigned Size = Record.size(); @@ -1336,13 +1338,14 @@ bool BitcodeReader::ParseConstants() { else V = ConstantDataArray::get(Context, Elts); } else { - return Error("Unknown element type in CE_DATA"); + return Error(InvalidTypeForValue); } break; } case bitc::CST_CODE_CE_BINOP: { // CE_BINOP: [opcode, opval, opval] - if (Record.size() < 3) return Error("Invalid CE_BINOP record"); + if (Record.size() < 3) + return Error(InvalidRecord); int Opc = GetDecodedBinaryOpcode(Record[0], CurTy); if (Opc < 0) { V = UndefValue::get(CurTy); // Unknown binop. @@ -1372,13 +1375,15 @@ bool BitcodeReader::ParseConstants() { break; } case bitc::CST_CODE_CE_CAST: { // CE_CAST: [opcode, opty, opval] - if (Record.size() < 3) return Error("Invalid CE_CAST record"); + if (Record.size() < 3) + return Error(InvalidRecord); int Opc = GetDecodedCastOpcode(Record[0]); if (Opc < 0) { V = UndefValue::get(CurTy); // Unknown cast. } else { Type *OpTy = getTypeByID(Record[1]); - if (!OpTy) return Error("Invalid CE_CAST record"); + if (!OpTy) + return Error(InvalidRecord); Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy); V = ConstantExpr::getCast(Opc, Op, CurTy); } @@ -1386,11 +1391,13 @@ bool BitcodeReader::ParseConstants() { } case bitc::CST_CODE_CE_INBOUNDS_GEP: case bitc::CST_CODE_CE_GEP: { // CE_GEP: [n x operands] - if (Record.size() & 1) return Error("Invalid CE_GEP record"); + if (Record.size() & 1) + return Error(InvalidRecord); SmallVector<Constant*, 16> Elts; for (unsigned i = 0, e = Record.size(); i != e; i += 2) { Type *ElTy = getTypeByID(Record[i]); - if (!ElTy) return Error("Invalid CE_GEP record"); + if (!ElTy) + return Error(InvalidRecord); Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy)); } ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end()); @@ -1400,7 +1407,8 @@ bool BitcodeReader::ParseConstants() { break; } case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] - if (Record.size() < 3) return Error("Invalid CE_SELECT record"); + if (Record.size() < 3) + return Error(InvalidRecord); Type *SelectorTy = Type::getInt1Ty(Context); @@ -1417,10 +1425,12 @@ bool BitcodeReader::ParseConstants() { break; } case bitc::CST_CODE_CE_EXTRACTELT: { // CE_EXTRACTELT: [opty, opval, opval] - if (Record.size() < 3) return Error("Invalid CE_EXTRACTELT record"); + if (Record.size() < 3) + return Error(InvalidRecord); VectorType *OpTy = dyn_cast_or_null<VectorType>(getTypeByID(Record[0])); - if (OpTy == 0) return Error("Invalid CE_EXTRACTELT record"); + if (OpTy == 0) + return Error(InvalidRecord); Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); Constant *Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context)); @@ -1430,7 +1440,7 @@ bool BitcodeReader::ParseConstants() { case bitc::CST_CODE_CE_INSERTELT: { // CE_INSERTELT: [opval, opval, opval] VectorType *OpTy = dyn_cast<VectorType>(CurTy); if (Record.size() < 3 || OpTy == 0) - return Error("Invalid CE_INSERTELT record"); + return Error(InvalidRecord); Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy); Constant *Op1 = ValueList.getConstantFwdRef(Record[1], OpTy->getElementType()); @@ -1442,7 +1452,7 @@ bool BitcodeReader::ParseConstants() { case bitc::CST_CODE_CE_SHUFFLEVEC: { // CE_SHUFFLEVEC: [opval, opval, opval] VectorType *OpTy = dyn_cast<VectorType>(CurTy); if (Record.size() < 3 || OpTy == 0) - return Error("Invalid CE_SHUFFLEVEC record"); + return Error(InvalidRecord); Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy); Constant *Op1 = ValueList.getConstantFwdRef(Record[1], OpTy); Type *ShufTy = VectorType::get(Type::getInt32Ty(Context), @@ -1456,7 +1466,7 @@ bool BitcodeReader::ParseConstants() { VectorType *OpTy = dyn_cast_or_null<VectorType>(getTypeByID(Record[0])); if (Record.size() < 4 || RTy == 0 || OpTy == 0) - return Error("Invalid CE_SHUFVEC_EX record"); + return Error(InvalidRecord); Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy); Type *ShufTy = VectorType::get(Type::getInt32Ty(Context), @@ -1466,9 +1476,11 @@ bool BitcodeReader::ParseConstants() { break; } case bitc::CST_CODE_CE_CMP: { // CE_CMP: [opty, opval, opval, pred] - if (Record.size() < 4) return Error("Invalid CE_CMP record"); + if (Record.size() < 4) + return Error(InvalidRecord); Type *OpTy = getTypeByID(Record[0]); - if (OpTy == 0) return Error("Invalid CE_CMP record"); + if (OpTy == 0) + return Error(InvalidRecord); Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy); @@ -1481,16 +1493,17 @@ bool BitcodeReader::ParseConstants() { // This maintains backward compatibility, pre-asm dialect keywords. // FIXME: Remove with the 4.0 release. case bitc::CST_CODE_INLINEASM_OLD: { - if (Record.size() < 2) return Error("Invalid INLINEASM record"); + if (Record.size() < 2) + return Error(InvalidRecord); std::string AsmStr, ConstrStr; bool HasSideEffects = Record[0] & 1; bool IsAlignStack = Record[0] >> 1; unsigned AsmStrSize = Record[1]; if (2+AsmStrSize >= Record.size()) - return Error("Invalid INLINEASM record"); + return Error(InvalidRecord); unsigned ConstStrSize = Record[2+AsmStrSize]; if (3+AsmStrSize+ConstStrSize > Record.size()) - return Error("Invalid INLINEASM record"); + return Error(InvalidRecord); for (unsigned i = 0; i != AsmStrSize; ++i) AsmStr += (char)Record[2+i]; @@ -1504,17 +1517,18 @@ bool BitcodeReader::ParseConstants() { // This version adds support for the asm dialect keywords (e.g., // inteldialect). case bitc::CST_CODE_INLINEASM: { - if (Record.size() < 2) return Error("Invalid INLINEASM record"); + if (Record.size() < 2) + return Error(InvalidRecord); std::string AsmStr, ConstrStr; bool HasSideEffects = Record[0] & 1; bool IsAlignStack = (Record[0] >> 1) & 1; unsigned AsmDialect = Record[0] >> 2; unsigned AsmStrSize = Record[1]; if (2+AsmStrSize >= Record.size()) - return Error("Invalid INLINEASM record"); + return Error(InvalidRecord); unsigned ConstStrSize = Record[2+AsmStrSize]; if (3+AsmStrSize+ConstStrSize > Record.size()) - return Error("Invalid INLINEASM record"); + return Error(InvalidRecord); for (unsigned i = 0; i != AsmStrSize; ++i) AsmStr += (char)Record[2+i]; @@ -1527,12 +1541,15 @@ bool BitcodeReader::ParseConstants() { break; } case bitc::CST_CODE_BLOCKADDRESS:{ - if (Record.size() < 3) return Error("Invalid CE_BLOCKADDRESS record"); + if (Record.size() < 3) + return Error(InvalidRecord); Type *FnTy = getTypeByID(Record[0]); - if (FnTy == 0) return Error("Invalid CE_BLOCKADDRESS record"); + if (FnTy == 0) + return Error(InvalidRecord); Function *Fn = dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy)); - if (Fn == 0) return Error("Invalid CE_BLOCKADDRESS record"); + if (Fn == 0) + return Error(InvalidRecord); // If the function is already parsed we can insert the block address right // away. @@ -1540,7 +1557,7 @@ bool BitcodeReader::ParseConstants() { Function::iterator BBI = Fn->begin(), BBE = Fn->end(); for (size_t I = 0, E = Record[2]; I != E; ++I) { if (BBI == BBE) - return Error("Invalid blockaddress block #"); + return Error(InvalidID); ++BBI; } V = BlockAddress::get(Fn, BBI); @@ -1563,9 +1580,9 @@ bool BitcodeReader::ParseConstants() { } } -bool BitcodeReader::ParseUseLists() { +error_code BitcodeReader::ParseUseLists() { if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID)) - return Error("Malformed block record"); + return Error(InvalidRecord); SmallVector<uint64_t, 64> Record; @@ -1576,9 +1593,9 @@ bool BitcodeReader::ParseUseLists() { switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: - return Error("malformed use list block"); + return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return false; + return error_code::success(); case BitstreamEntry::Record: // The interesting case. break; @@ -1592,7 +1609,7 @@ bool BitcodeReader::ParseUseLists() { case bitc::USELIST_CODE_ENTRY: { // USELIST_CODE_ENTRY: TBD. unsigned RecordLength = Record.size(); if (RecordLength < 1) - return Error ("Invalid UseList reader!"); + return Error(InvalidRecord); UseListRecords.push_back(Record); break; } @@ -1603,10 +1620,10 @@ bool BitcodeReader::ParseUseLists() { /// RememberAndSkipFunctionBody - When we see the block for a function body, /// remember where it is and then skip it. This lets us lazily deserialize the /// functions. -bool BitcodeReader::RememberAndSkipFunctionBody() { +error_code BitcodeReader::RememberAndSkipFunctionBody() { // Get the function we are talking about. if (FunctionsWithBodies.empty()) - return Error("Insufficient function protos"); + return Error(InsufficientFunctionProtos); Function *Fn = FunctionsWithBodies.back(); FunctionsWithBodies.pop_back(); @@ -1617,15 +1634,15 @@ bool BitcodeReader::RememberAndSkipFunctionBody() { // Skip over the function block for now. if (Stream.SkipBlock()) - return Error("Malformed block record"); - return false; + return Error(InvalidRecord); + return error_code::success(); } -bool BitcodeReader::GlobalCleanup() { +error_code BitcodeReader::GlobalCleanup() { // Patch the initializers for globals and aliases up. ResolveGlobalAndAliasInits(); if (!GlobalInits.empty() || !AliasInits.empty()) - return Error("Malformed global initializer set"); + return Error(MalformedGlobalInitializerSet); // Look for intrinsic functions which need to be upgraded at some point for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); @@ -1644,14 +1661,14 @@ bool BitcodeReader::GlobalCleanup() { // want lazy deserialization. std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits); std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits); - return false; + return error_code::success(); } -bool BitcodeReader::ParseModule(bool Resume) { +error_code BitcodeReader::ParseModule(bool Resume) { if (Resume) Stream.JumpToBit(NextUnreadBit); else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return Error("Malformed block record"); + return Error(InvalidRecord); SmallVector<uint64_t, 64> Record; std::vector<std::string> SectionTable; @@ -1663,8 +1680,7 @@ bool BitcodeReader::ParseModule(bool Resume) { switch (Entry.Kind) { case BitstreamEntry::Error: - Error("malformed module block"); - return true; + return Error(MalformedBlock); case BitstreamEntry::EndBlock: return GlobalCleanup(); @@ -1672,49 +1688,51 @@ bool BitcodeReader::ParseModule(bool Resume) { switch (Entry.ID) { default: // Skip unknown content. if (Stream.SkipBlock()) - return Error("Malformed block record"); + return Error(InvalidRecord); break; case bitc::BLOCKINFO_BLOCK_ID: if (Stream.ReadBlockInfoBlock()) - return Error("Malformed BlockInfoBlock"); + return Error(MalformedBlock); break; case bitc::PARAMATTR_BLOCK_ID: - if (ParseAttributeBlock()) - return true; + if (error_code EC = ParseAttributeBlock()) + return EC; break; case bitc::PARAMATTR_GROUP_BLOCK_ID: - if (ParseAttributeGroupBlock()) - return true; + if (error_code EC = ParseAttributeGroupBlock()) + return EC; break; case bitc::TYPE_BLOCK_ID_NEW: - if (ParseTypeTable()) - return true; + if (error_code EC = ParseTypeTable()) + return EC; break; case bitc::VALUE_SYMTAB_BLOCK_ID: - if (ParseValueSymbolTable()) - return true; + if (error_code EC = ParseValueSymbolTable()) + return EC; SeenValueSymbolTable = true; break; case bitc::CONSTANTS_BLOCK_ID: - if (ParseConstants() || ResolveGlobalAndAliasInits()) - return true; + if (error_code EC = ParseConstants()) + return EC; + if (error_code EC = ResolveGlobalAndAliasInits()) + return EC; break; case bitc::METADATA_BLOCK_ID: - if (ParseMetadata()) - return true; + if (error_code EC = ParseMetadata()) + return EC; break; case bitc::FUNCTION_BLOCK_ID: // If this is the first function body we've seen, reverse the // FunctionsWithBodies list. if (!SeenFirstFunctionBody) { std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end()); - if (GlobalCleanup()) - return true; + if (error_code EC = GlobalCleanup()) + return EC; SeenFirstFunctionBody = true; } - if (RememberAndSkipFunctionBody()) - return true; + if (error_code EC = RememberAndSkipFunctionBody()) + return EC; // For streaming bitcode, suspend parsing when we reach the function // bodies. Subsequent materialization calls will resume it when // necessary. For streaming, the function bodies must be at the end of @@ -1723,12 +1741,12 @@ bool BitcodeReader::ParseModule(bool Resume) { // just finish the parse now. if (LazyStreamer && SeenValueSymbolTable) { NextUnreadBit = Stream.GetCurrentBitNo(); - return false; + return error_code::success(); } break; case bitc::USELIST_BLOCK_ID: - if (ParseUseLists()) - return true; + if (error_code EC = ParseUseLists()) + return EC; break; } continue; @@ -1744,11 +1762,12 @@ bool BitcodeReader::ParseModule(bool Resume) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_VERSION: { // VERSION: [version#] if (Record.size() < 1) - return Error("Malformed MODULE_CODE_VERSION"); + return Error(InvalidRecord); // Only version #0 and #1 are supported so far. unsigned module_version = Record[0]; switch (module_version) { - default: return Error("Unknown bitstream version!"); + default: + return Error(InvalidValue); case 0: UseRelativeIDs = false; break; @@ -1761,21 +1780,21 @@ bool BitcodeReader::ParseModule(bool Resume) { case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] std::string S; if (ConvertToString(Record, 0, S)) - return Error("Invalid MODULE_CODE_TRIPLE record"); + return Error(InvalidRecord); TheModule->setTargetTriple(S); break; } case bitc::MODULE_CODE_DATALAYOUT: { // DATALAYOUT: [strchr x N] std::string S; if (ConvertToString(Record, 0, S)) - return Error("Invalid MODULE_CODE_DATALAYOUT record"); + return Error(InvalidRecord); TheModule->setDataLayout(S); break; } case bitc::MODULE_CODE_ASM: { // ASM: [strchr x N] std::string S; if (ConvertToString(Record, 0, S)) - return Error("Invalid MODULE_CODE_ASM record"); + return Error(InvalidRecord); TheModule->setModuleInlineAsm(S); break; } @@ -1783,21 +1802,21 @@ bool BitcodeReader::ParseModule(bool Resume) { // FIXME: Remove in 4.0. std::string S; if (ConvertToString(Record, 0, S)) - return Error("Invalid MODULE_CODE_DEPLIB record"); + return Error(InvalidRecord); // Ignore value. break; } case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N] std::string S; if (ConvertToString(Record, 0, S)) - return Error("Invalid MODULE_CODE_SECTIONNAME record"); + return Error(InvalidRecord); SectionTable.push_back(S); break; } case bitc::MODULE_CODE_GCNAME: { // SECTIONNAME: [strchr x N] std::string S; if (ConvertToString(Record, 0, S)) - return Error("Invalid MODULE_CODE_GCNAME record"); + return Error(InvalidRecord); GCTable.push_back(S); break; } @@ -1806,11 +1825,12 @@ bool BitcodeReader::ParseModule(bool Resume) { // unnamed_addr] case bitc::MODULE_CODE_GLOBALVAR: { if (Record.size() < 6) - return Error("Invalid MODULE_CODE_GLOBALVAR record"); + return Error(InvalidRecord); Type *Ty = getTypeByID(Record[0]); - if (!Ty) return Error("Invalid MODULE_CODE_GLOBALVAR record"); + if (!Ty) + return Error(InvalidRecord); if (!Ty->isPointerTy()) - return Error("Global not a pointer type!"); + return Error(InvalidTypeForValue); unsigned AddressSpace = cast<PointerType>(Ty)->getAddressSpace(); Ty = cast<PointerType>(Ty)->getElementType(); @@ -1820,7 +1840,7 @@ bool BitcodeReader::ParseModule(bool Resume) { std::string Section; if (Record[5]) { if (Record[5]-1 >= SectionTable.size()) - return Error("Invalid section ID"); + return Error(InvalidID); Section = SectionTable[Record[5]-1]; } GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility; @@ -1859,15 +1879,16 @@ bool BitcodeReader::ParseModule(bool Resume) { // alignment, section, visibility, gc, unnamed_addr] case bitc::MODULE_CODE_FUNCTION: { if (Record.size() < 8) - return Error("Invalid MODULE_CODE_FUNCTION record"); + return Error(InvalidRecord); Type *Ty = getTypeByID(Record[0]); - if (!Ty) return Error("Invalid MODULE_CODE_FUNCTION record"); + if (!Ty) + return Error(InvalidRecord); if (!Ty->isPointerTy()) - return Error("Function not a pointer type!"); + return Error(InvalidTypeForValue); FunctionType *FTy = dyn_cast<FunctionType>(cast<PointerType>(Ty)->getElementType()); if (!FTy) - return Error("Function not a pointer to function type!"); + return Error(InvalidTypeForValue); Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage, "", TheModule); @@ -1880,13 +1901,13 @@ bool BitcodeReader::ParseModule(bool Resume) { Func->setAlignment((1 << Record[5]) >> 1); if (Record[6]) { if (Record[6]-1 >= SectionTable.size()) - return Error("Invalid section ID"); + return Error(InvalidID); Func->setSection(SectionTable[Record[6]-1]); } Func->setVisibility(GetDecodedVisibility(Record[7])); if (Record.size() > 8 && Record[8]) { if (Record[8]-1 > GCTable.size()) - return Error("Invalid GC ID"); + return Error(InvalidID); Func->setGC(GCTable[Record[8]-1].c_str()); } bool UnnamedAddr = false; @@ -1909,11 +1930,12 @@ bool BitcodeReader::ParseModule(bool Resume) { // ALIAS: [alias type, aliasee val#, linkage, visibility] case bitc::MODULE_CODE_ALIAS: { if (Record.size() < 3) - return Error("Invalid MODULE_ALIAS record"); + return Error(InvalidRecord); Type *Ty = getTypeByID(Record[0]); - if (!Ty) return Error("Invalid MODULE_ALIAS record"); + if (!Ty) + return Error(InvalidRecord); if (!Ty->isPointerTy()) - return Error("Function not a pointer type!"); + return Error(InvalidTypeForValue); GlobalAlias *NewGA = new GlobalAlias(Ty, GetDecodedLinkage(Record[2]), "", 0, TheModule); @@ -1928,7 +1950,7 @@ bool BitcodeReader::ParseModule(bool Resume) { case bitc::MODULE_CODE_PURGEVALS: // Trim down the value list to the specified size. if (Record.size() < 1 || Record[0] > ValueList.size()) - return Error("Invalid MODULE_PURGEVALS record"); + return Error(InvalidRecord); ValueList.shrinkTo(Record[0]); break; } @@ -1936,10 +1958,11 @@ bool BitcodeReader::ParseModule(bool Resume) { } } -bool BitcodeReader::ParseBitcodeInto(Module *M) { +error_code BitcodeReader::ParseBitcodeInto(Module *M) { TheModule = 0; - if (InitStream()) return true; + if (error_code EC = InitStream()) + return EC; // Sniff for the signature. if (Stream.Read(8) != 'B' || @@ -1948,42 +1971,42 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) { Stream.Read(4) != 0xC || Stream.Read(4) != 0xE || Stream.Read(4) != 0xD) - return Error("Invalid bitcode signature"); + return Error(InvalidBitcodeSignature); // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. while (1) { if (Stream.AtEndOfStream()) - return false; + return error_code::success(); BitstreamEntry Entry = Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); switch (Entry.Kind) { case BitstreamEntry::Error: - Error("malformed module file"); - return true; + return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return false; + return error_code::success(); case BitstreamEntry::SubBlock: switch (Entry.ID) { case bitc::BLOCKINFO_BLOCK_ID: if (Stream.ReadBlockInfoBlock()) - return Error("Malformed BlockInfoBlock"); + return Error(MalformedBlock); break; case bitc::MODULE_BLOCK_ID: // Reject multiple MODULE_BLOCK's in a single bitstream. if (TheModule) - return Error("Multiple MODULE_BLOCKs in same stream"); + return Error(InvalidMultipleBlocks); TheModule = M; - if (ParseModule(false)) - return true; - if (LazyStreamer) return false; + if (error_code EC = ParseModule(false)) + return EC; + if (LazyStreamer) + return error_code::success(); break; default: if (Stream.SkipBlock()) - return Error("Malformed block record"); + return Error(InvalidRecord); break; } continue; @@ -1996,16 +2019,16 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) { if (Stream.getAbbrevIDWidth() == 2 && Entry.ID == 2 && Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a && Stream.AtEndOfStream()) - return false; + return error_code::success(); - return Error("Invalid record at top-level"); + return Error(InvalidRecord); } } } -bool BitcodeReader::ParseModuleTriple(std::string &Triple) { +error_code BitcodeReader::ParseModuleTriple(std::string &Triple) { if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return Error("Malformed block record"); + return Error(InvalidRecord); SmallVector<uint64_t, 64> Record; @@ -2016,9 +2039,9 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) { switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: - return Error("malformed module block"); + return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return false; + return error_code::success(); case BitstreamEntry::Record: // The interesting case. break; @@ -2030,7 +2053,7 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) { case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] std::string S; if (ConvertToString(Record, 0, S)) - return Error("Invalid MODULE_CODE_TRIPLE record"); + return Error(InvalidRecord); Triple = S; break; } @@ -2039,8 +2062,9 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) { } } -bool BitcodeReader::ParseTriple(std::string &Triple) { - if (InitStream()) return true; +error_code BitcodeReader::ParseTriple(std::string &Triple) { + if (error_code EC = InitStream()) + return EC; // Sniff for the signature. if (Stream.Read(8) != 'B' || @@ -2049,7 +2073,7 @@ bool BitcodeReader::ParseTriple(std::string &Triple) { Stream.Read(4) != 0xC || Stream.Read(4) != 0xE || Stream.Read(4) != 0xD) - return Error("Invalid bitcode signature"); + return Error(InvalidBitcodeSignature); // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. @@ -2058,20 +2082,17 @@ bool BitcodeReader::ParseTriple(std::string &Triple) { switch (Entry.Kind) { case BitstreamEntry::Error: - Error("malformed module file"); - return true; + return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return false; + return error_code::success(); case BitstreamEntry::SubBlock: if (Entry.ID == bitc::MODULE_BLOCK_ID) return ParseModuleTriple(Triple); // Ignore other sub-blocks. - if (Stream.SkipBlock()) { - Error("malformed block record in AST file"); - return true; - } + if (Stream.SkipBlock()) + return Error(MalformedBlock); continue; case BitstreamEntry::Record: @@ -2082,9 +2103,9 @@ bool BitcodeReader::ParseTriple(std::string &Triple) { } /// ParseMetadataAttachment - Parse metadata attachments. -bool BitcodeReader::ParseMetadataAttachment() { +error_code BitcodeReader::ParseMetadataAttachment() { if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) - return Error("Malformed block record"); + return Error(InvalidRecord); SmallVector<uint64_t, 64> Record; while (1) { @@ -2093,9 +2114,9 @@ bool BitcodeReader::ParseMetadataAttachment() { switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: - return Error("malformed metadata block"); + return Error(MalformedBlock); case BitstreamEntry::EndBlock: - return false; + return error_code::success(); case BitstreamEntry::Record: // The interesting case. break; @@ -2109,14 +2130,14 @@ bool BitcodeReader::ParseMetadataAttachment() { case bitc::METADATA_ATTACHMENT: { unsigned RecordLength = Record.size(); if (Record.empty() || (RecordLength - 1) % 2 == 1) - return Error ("Invalid METADATA_ATTACHMENT reader!"); + return Error(InvalidRecord); Instruction *Inst = InstructionList[Record[0]]; for (unsigned i = 1; i != RecordLength; i = i+2) { unsigned Kind = Record[i]; DenseMap<unsigned, unsigned>::iterator I = MDKindMap.find(Kind); if (I == MDKindMap.end()) - return Error("Invalid metadata kind ID"); + return Error(InvalidID); Value *Node = MDValueList.getValueFwdRef(Record[i+1]); Inst->setMetadata(I->second, cast<MDNode>(Node)); if (I->second == LLVMContext::MD_tbaa) @@ -2129,9 +2150,9 @@ bool BitcodeReader::ParseMetadataAttachment() { } /// ParseFunctionBody - Lazily parse the specified function body block. -bool BitcodeReader::ParseFunctionBody(Function *F) { +error_code BitcodeReader::ParseFunctionBody(Function *F) { if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID)) - return Error("Malformed block record"); + return Error(InvalidRecord); InstructionList.clear(); unsigned ModuleValueListSize = ValueList.size(); @@ -2154,7 +2175,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { switch (Entry.Kind) { case BitstreamEntry::Error: - return Error("Bitcode error in function block"); + return Error(MalformedBlock); case BitstreamEntry::EndBlock: goto OutOfRecordLoop; @@ -2162,20 +2183,24 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { switch (Entry.ID) { default: // Skip unknown content. if (Stream.SkipBlock()) - return Error("Malformed block record"); + return Error(InvalidRecord); break; case bitc::CONSTANTS_BLOCK_ID: - if (ParseConstants()) return true; + if (error_code EC = ParseConstants()) + return EC; NextValueNo = ValueList.size(); break; case bitc::VALUE_SYMTAB_BLOCK_ID: - if (ParseValueSymbolTable()) return true; + if (error_code EC = ParseValueSymbolTable()) + return EC; break; case bitc::METADATA_ATTACHMENT_ID: - if (ParseMetadataAttachment()) return true; + if (error_code EC = ParseMetadataAttachment()) + return EC; break; case bitc::METADATA_BLOCK_ID: - if (ParseMetadata()) return true; + if (error_code EC = ParseMetadata()) + return EC; break; } continue; @@ -2191,10 +2216,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned BitCode = Stream.readRecord(Entry.ID, Record); switch (BitCode) { default: // Default behavior: reject - return Error("Unknown instruction"); + return Error(InvalidValue); case bitc::FUNC_CODE_DECLAREBLOCKS: // DECLAREBLOCKS: [nblocks] if (Record.size() < 1 || Record[0] == 0) - return Error("Invalid DECLAREBLOCKS record"); + return Error(InvalidRecord); // Create all the basic blocks for the function. FunctionBBs.resize(Record[0]); for (unsigned i = 0, e = FunctionBBs.size(); i != e; ++i) @@ -2214,7 +2239,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { !FunctionBBs[CurBBNo-1]->empty()) I = &FunctionBBs[CurBBNo-1]->back(); - if (I == 0) return Error("Invalid DEBUG_LOC_AGAIN record"); + if (I == 0) + return Error(InvalidRecord); I->setDebugLoc(LastLoc); I = 0; continue; @@ -2227,7 +2253,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { !FunctionBBs[CurBBNo-1]->empty()) I = &FunctionBBs[CurBBNo-1]->back(); if (I == 0 || Record.size() < 4) - return Error("Invalid FUNC_CODE_DEBUG_LOC record"); + return Error(InvalidRecord); unsigned Line = Record[0], Col = Record[1]; unsigned ScopeID = Record[2], IAID = Record[3]; @@ -2247,10 +2273,11 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) || OpNum+1 > Record.size()) - return Error("Invalid BINOP record"); + return Error(InvalidRecord); int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType()); - if (Opc == -1) return Error("Invalid BINOP record"); + if (Opc == -1) + return Error(InvalidRecord); I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS); InstructionList.push_back(I); if (OpNum < Record.size()) { @@ -2292,12 +2319,12 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op) || OpNum+2 != Record.size()) - return Error("Invalid CAST record"); + return Error(InvalidRecord); Type *ResTy = getTypeByID(Record[OpNum]); int Opc = GetDecodedCastOpcode(Record[OpNum+1]); if (Opc == -1 || ResTy == 0) - return Error("Invalid CAST record"); + return Error(InvalidRecord); I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy); InstructionList.push_back(I); break; @@ -2307,13 +2334,13 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *BasePtr; if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr)) - return Error("Invalid GEP record"); + return Error(InvalidRecord); SmallVector<Value*, 16> GEPIdx; while (OpNum != Record.size()) { Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op)) - return Error("Invalid GEP record"); + return Error(InvalidRecord); GEPIdx.push_back(Op); } @@ -2329,14 +2356,14 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Agg; if (getValueTypePair(Record, OpNum, NextValueNo, Agg)) - return Error("Invalid EXTRACTVAL record"); + return Error(InvalidRecord); SmallVector<unsigned, 4> EXTRACTVALIdx; for (unsigned RecSize = Record.size(); OpNum != RecSize; ++OpNum) { uint64_t Index = Record[OpNum]; if ((unsigned)Index != Index) - return Error("Invalid EXTRACTVAL index"); + return Error(InvalidValue); EXTRACTVALIdx.push_back((unsigned)Index); } @@ -2350,17 +2377,17 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Agg; if (getValueTypePair(Record, OpNum, NextValueNo, Agg)) - return Error("Invalid INSERTVAL record"); + return Error(InvalidRecord); Value *Val; if (getValueTypePair(Record, OpNum, NextValueNo, Val)) - return Error("Invalid INSERTVAL record"); + return Error(InvalidRecord); SmallVector<unsigned, 4> INSERTVALIdx; for (unsigned RecSize = Record.size(); OpNum != RecSize; ++OpNum) { uint64_t Index = Record[OpNum]; if ((unsigned)Index != Index) - return Error("Invalid INSERTVAL index"); + return Error(InvalidValue); INSERTVALIdx.push_back((unsigned)Index); } @@ -2377,7 +2404,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) || popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context), Cond)) - return Error("Invalid SELECT record"); + return Error(InvalidRecord); I = SelectInst::Create(Cond, TrueVal, FalseVal); InstructionList.push_back(I); @@ -2392,18 +2419,18 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) || getValueTypePair(Record, OpNum, NextValueNo, Cond)) - return Error("Invalid SELECT record"); + return Error(InvalidRecord); // select condition can be either i1 or [N x i1] if (VectorType* vector_type = dyn_cast<VectorType>(Cond->getType())) { // expect <n x i1> if (vector_type->getElementType() != Type::getInt1Ty(Context)) - return Error("Invalid SELECT condition type"); + return Error(InvalidTypeForValue); } else { // expect i1 if (Cond->getType() != Type::getInt1Ty(Context)) - return Error("Invalid SELECT condition type"); + return Error(InvalidTypeForValue); } I = SelectInst::Create(Cond, TrueVal, FalseVal); @@ -2416,7 +2443,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { Value *Vec, *Idx; if (getValueTypePair(Record, OpNum, NextValueNo, Vec) || popValue(Record, OpNum, NextValueNo, Type::getInt32Ty(Context), Idx)) - return Error("Invalid EXTRACTELT record"); + return Error(InvalidRecord); I = ExtractElementInst::Create(Vec, Idx); InstructionList.push_back(I); break; @@ -2429,7 +2456,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { popValue(Record, OpNum, NextValueNo, cast<VectorType>(Vec->getType())->getElementType(), Elt) || popValue(Record, OpNum, NextValueNo, Type::getInt32Ty(Context), Idx)) - return Error("Invalid INSERTELT record"); + return Error(InvalidRecord); I = InsertElementInst::Create(Vec, Elt, Idx); InstructionList.push_back(I); break; @@ -2440,10 +2467,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { Value *Vec1, *Vec2, *Mask; if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) || popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec2)) - return Error("Invalid SHUFFLEVEC record"); + return Error(InvalidRecord); if (getValueTypePair(Record, OpNum, NextValueNo, Mask)) - return Error("Invalid SHUFFLEVEC record"); + return Error(InvalidRecord); I = new ShuffleVectorInst(Vec1, Vec2, Mask); InstructionList.push_back(I); break; @@ -2461,7 +2488,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) || OpNum+1 != Record.size()) - return Error("Invalid CMP record"); + return Error(InvalidRecord); if (LHS->getType()->isFPOrFPVectorTy()) I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS); @@ -2483,9 +2510,9 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Op = NULL; if (getValueTypePair(Record, OpNum, NextValueNo, Op)) - return Error("Invalid RET record"); + return Error(InvalidRecord); if (OpNum != Record.size()) - return Error("Invalid RET record"); + return Error(InvalidRecord); I = ReturnInst::Create(Context, Op); InstructionList.push_back(I); @@ -2493,10 +2520,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { } case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#] if (Record.size() != 1 && Record.size() != 3) - return Error("Invalid BR record"); + return Error(InvalidRecord); BasicBlock *TrueDest = getBasicBlock(Record[0]); if (TrueDest == 0) - return Error("Invalid BR record"); + return Error(InvalidRecord); if (Record.size() == 1) { I = BranchInst::Create(TrueDest); @@ -2507,7 +2534,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { Value *Cond = getValue(Record, 2, NextValueNo, Type::getInt1Ty(Context)); if (FalseDest == 0 || Cond == 0) - return Error("Invalid BR record"); + return Error(InvalidRecord); I = BranchInst::Create(TrueDest, FalseDest, Cond); InstructionList.push_back(I); } @@ -2527,7 +2554,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { Value *Cond = getValue(Record, 2, NextValueNo, OpTy); BasicBlock *Default = getBasicBlock(Record[3]); if (OpTy == 0 || Cond == 0 || Default == 0) - return Error("Invalid SWITCH record"); + return Error(InvalidRecord); unsigned NumCases = Record[4]; @@ -2579,12 +2606,12 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { // Old SwitchInst format without case ranges. if (Record.size() < 3 || (Record.size() & 1) == 0) - return Error("Invalid SWITCH record"); + return Error(InvalidRecord); Type *OpTy = getTypeByID(Record[0]); Value *Cond = getValue(Record, 1, NextValueNo, OpTy); BasicBlock *Default = getBasicBlock(Record[2]); if (OpTy == 0 || Cond == 0 || Default == 0) - return Error("Invalid SWITCH record"); + return Error(InvalidRecord); unsigned NumCases = (Record.size()-3)/2; SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases); InstructionList.push_back(SI); @@ -2594,7 +2621,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { BasicBlock *DestBB = getBasicBlock(Record[1+3+i*2]); if (CaseVal == 0 || DestBB == 0) { delete SI; - return Error("Invalid SWITCH record!"); + return Error(InvalidRecord); } SI->addCase(CaseVal, DestBB); } @@ -2603,11 +2630,11 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { } case bitc::FUNC_CODE_INST_INDIRECTBR: { // INDIRECTBR: [opty, op0, op1, ...] if (Record.size() < 2) - return Error("Invalid INDIRECTBR record"); + return Error(InvalidRecord); Type *OpTy = getTypeByID(Record[0]); Value *Address = getValue(Record, 1, NextValueNo, OpTy); if (OpTy == 0 || Address == 0) - return Error("Invalid INDIRECTBR record"); + return Error(InvalidRecord); unsigned NumDests = Record.size()-2; IndirectBrInst *IBI = IndirectBrInst::Create(Address, NumDests); InstructionList.push_back(IBI); @@ -2616,7 +2643,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { IBI->addDestination(DestBB); } else { delete IBI; - return Error("Invalid INDIRECTBR record!"); + return Error(InvalidRecord); } } I = IBI; @@ -2625,7 +2652,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_INVOKE: { // INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...] - if (Record.size() < 4) return Error("Invalid INVOKE record"); + if (Record.size() < 4) + return Error(InvalidRecord); AttributeSet PAL = getAttributes(Record[0]); unsigned CCInfo = Record[1]; BasicBlock *NormalBB = getBasicBlock(Record[2]); @@ -2634,7 +2662,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 4; Value *Callee; if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) - return Error("Invalid INVOKE record"); + return Error(InvalidRecord); PointerType *CalleeTy = dyn_cast<PointerType>(Callee->getType()); FunctionType *FTy = !CalleeTy ? 0 : @@ -2643,24 +2671,25 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { // Check that the right number of fixed parameters are here. if (FTy == 0 || NormalBB == 0 || UnwindBB == 0 || Record.size() < OpNum+FTy->getNumParams()) - return Error("Invalid INVOKE record"); + return Error(InvalidRecord); SmallVector<Value*, 16> Ops; for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { Ops.push_back(getValue(Record, OpNum, NextValueNo, FTy->getParamType(i))); - if (Ops.back() == 0) return Error("Invalid INVOKE record"); + if (Ops.back() == 0) + return Error(InvalidRecord); } if (!FTy->isVarArg()) { if (Record.size() != OpNum) - return Error("Invalid INVOKE record"); + return Error(InvalidRecord); } else { // Read type/value pairs for varargs params. while (OpNum != Record.size()) { Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op)) - return Error("Invalid INVOKE record"); + return Error(InvalidRecord); Ops.push_back(Op); } } @@ -2676,7 +2705,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned Idx = 0; Value *Val = 0; if (getValueTypePair(Record, Idx, NextValueNo, Val)) - return Error("Invalid RESUME record"); + return Error(InvalidRecord); I = ResumeInst::Create(Val); InstructionList.push_back(I); break; @@ -2687,9 +2716,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { break; case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...] if (Record.size() < 1 || ((Record.size()-1)&1)) - return Error("Invalid PHI record"); + return Error(InvalidRecord); Type *Ty = getTypeByID(Record[0]); - if (!Ty) return Error("Invalid PHI record"); + if (!Ty) + return Error(InvalidRecord); PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2); InstructionList.push_back(PN); @@ -2704,7 +2734,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { else V = getValue(Record, 1+i, NextValueNo, Ty); BasicBlock *BB = getBasicBlock(Record[2+i]); - if (!V || !BB) return Error("Invalid PHI record"); + if (!V || !BB) + return Error(InvalidRecord); PN->addIncoming(V, BB); } I = PN; @@ -2715,12 +2746,13 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { // LANDINGPAD: [ty, val, val, num, (id0,val0 ...)?] unsigned Idx = 0; if (Record.size() < 4) - return Error("Invalid LANDINGPAD record"); + return Error(InvalidRecord); Type *Ty = getTypeByID(Record[Idx++]); - if (!Ty) return Error("Invalid LANDINGPAD record"); + if (!Ty) + return Error(InvalidRecord); Value *PersFn = 0; if (getValueTypePair(Record, Idx, NextValueNo, PersFn)) - return Error("Invalid LANDINGPAD record"); + return Error(InvalidRecord); bool IsCleanup = !!Record[Idx++]; unsigned NumClauses = Record[Idx++]; @@ -2733,7 +2765,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, Idx, NextValueNo, Val)) { delete LP; - return Error("Invalid LANDINGPAD record"); + return Error(InvalidRecord); } assert((CT != LandingPadInst::Catch || @@ -2752,13 +2784,14 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align] if (Record.size() != 4) - return Error("Invalid ALLOCA record"); + return Error(InvalidRecord); PointerType *Ty = dyn_cast_or_null<PointerType>(getTypeByID(Record[0])); Type *OpTy = getTypeByID(Record[1]); Value *Size = getFnValueByID(Record[2], OpTy); unsigned Align = Record[3]; - if (!Ty || !Size) return Error("Invalid ALLOCA record"); + if (!Ty || !Size) + return Error(InvalidRecord); I = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1); InstructionList.push_back(I); break; @@ -2768,7 +2801,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op) || OpNum+2 != Record.size()) - return Error("Invalid LOAD record"); + return Error(InvalidRecord); I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1); InstructionList.push_back(I); @@ -2780,15 +2813,15 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op) || OpNum+4 != Record.size()) - return Error("Invalid LOADATOMIC record"); + return Error(InvalidRecord); AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]); if (Ordering == NotAtomic || Ordering == Release || Ordering == AcquireRelease) - return Error("Invalid LOADATOMIC record"); + return Error(InvalidRecord); if (Ordering != NotAtomic && Record[OpNum] == 0) - return Error("Invalid LOADATOMIC record"); + return Error(InvalidRecord); SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]); I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1, @@ -2803,7 +2836,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { popValue(Record, OpNum, NextValueNo, cast<PointerType>(Ptr->getType())->getElementType(), Val) || OpNum+2 != Record.size()) - return Error("Invalid STORE record"); + return Error(InvalidRecord); I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1); InstructionList.push_back(I); @@ -2817,15 +2850,15 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { popValue(Record, OpNum, NextValueNo, cast<PointerType>(Ptr->getType())->getElementType(), Val) || OpNum+4 != Record.size()) - return Error("Invalid STOREATOMIC record"); + return Error(InvalidRecord); AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]); if (Ordering == NotAtomic || Ordering == Acquire || Ordering == AcquireRelease) - return Error("Invalid STOREATOMIC record"); + return Error(InvalidRecord); SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]); if (Ordering != NotAtomic && Record[OpNum] == 0) - return Error("Invalid STOREATOMIC record"); + return Error(InvalidRecord); I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1, Ordering, SynchScope); @@ -2842,10 +2875,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { popValue(Record, OpNum, NextValueNo, cast<PointerType>(Ptr->getType())->getElementType(), New) || OpNum+3 != Record.size()) - return Error("Invalid CMPXCHG record"); + return Error(InvalidRecord); AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+1]); if (Ordering == NotAtomic || Ordering == Unordered) - return Error("Invalid CMPXCHG record"); + return Error(InvalidRecord); SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+2]); I = new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, SynchScope); cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]); @@ -2860,14 +2893,14 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { popValue(Record, OpNum, NextValueNo, cast<PointerType>(Ptr->getType())->getElementType(), Val) || OpNum+4 != Record.size()) - return Error("Invalid ATOMICRMW record"); + return Error(InvalidRecord); AtomicRMWInst::BinOp Operation = GetDecodedRMWOperation(Record[OpNum]); if (Operation < AtomicRMWInst::FIRST_BINOP || Operation > AtomicRMWInst::LAST_BINOP) - return Error("Invalid ATOMICRMW record"); + return Error(InvalidRecord); AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]); if (Ordering == NotAtomic || Ordering == Unordered) - return Error("Invalid ATOMICRMW record"); + return Error(InvalidRecord); SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]); I = new AtomicRMWInst(Operation, Ptr, Val, Ordering, SynchScope); cast<AtomicRMWInst>(I)->setVolatile(Record[OpNum+1]); @@ -2876,11 +2909,11 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { } case bitc::FUNC_CODE_INST_FENCE: { // FENCE:[ordering, synchscope] if (2 != Record.size()) - return Error("Invalid FENCE record"); + return Error(InvalidRecord); AtomicOrdering Ordering = GetDecodedOrdering(Record[0]); if (Ordering == NotAtomic || Ordering == Unordered || Ordering == Monotonic) - return Error("Invalid FENCE record"); + return Error(InvalidRecord); SynchronizationScope SynchScope = GetDecodedSynchScope(Record[1]); I = new FenceInst(Context, Ordering, SynchScope); InstructionList.push_back(I); @@ -2889,7 +2922,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_CALL: { // CALL: [paramattrs, cc, fnty, fnid, arg0, arg1...] if (Record.size() < 3) - return Error("Invalid CALL record"); + return Error(InvalidRecord); AttributeSet PAL = getAttributes(Record[0]); unsigned CCInfo = Record[1]; @@ -2897,13 +2930,13 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 2; Value *Callee; if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) - return Error("Invalid CALL record"); + return Error(InvalidRecord); PointerType *OpTy = dyn_cast<PointerType>(Callee->getType()); FunctionType *FTy = 0; if (OpTy) FTy = dyn_cast<FunctionType>(OpTy->getElementType()); if (!FTy || Record.size() < FTy->getNumParams()+OpNum) - return Error("Invalid CALL record"); + return Error(InvalidRecord); SmallVector<Value*, 16> Args; // Read the fixed params. @@ -2913,18 +2946,19 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { else Args.push_back(getValue(Record, OpNum, NextValueNo, FTy->getParamType(i))); - if (Args.back() == 0) return Error("Invalid CALL record"); + if (Args.back() == 0) + return Error(InvalidRecord); } // Read type/value pairs for varargs params. if (!FTy->isVarArg()) { if (OpNum != Record.size()) - return Error("Invalid CALL record"); + return Error(InvalidRecord); } else { while (OpNum != Record.size()) { Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op)) - return Error("Invalid CALL record"); + return Error(InvalidRecord); Args.push_back(Op); } } @@ -2939,12 +2973,12 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { } case bitc::FUNC_CODE_INST_VAARG: { // VAARG: [valistty, valist, instty] if (Record.size() < 3) - return Error("Invalid VAARG record"); + return Error(InvalidRecord); Type *OpTy = getTypeByID(Record[0]); Value *Op = getValue(Record, 1, NextValueNo, OpTy); Type *ResTy = getTypeByID(Record[2]); if (!OpTy || !Op || !ResTy) - return Error("Invalid VAARG record"); + return Error(InvalidRecord); I = new VAArgInst(Op, ResTy); InstructionList.push_back(I); break; @@ -2955,7 +2989,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { // this file. if (CurBB == 0) { delete I; - return Error("Invalid instruction with no BB"); + return Error(InvalidInstructionWithNoBB); } CurBB->getInstList().push_back(I); @@ -2982,7 +3016,7 @@ OutOfRecordLoop: delete A; } } - return Error("Never resolved value found in function!"); + return Error(NeverResolvedValueFoundInFunction); } } @@ -2998,7 +3032,7 @@ OutOfRecordLoop: for (unsigned i = 0, e = RefList.size(); i != e; ++i) { unsigned BlockIdx = RefList[i].first; if (BlockIdx >= FunctionBBs.size()) - return Error("Invalid blockaddress block #"); + return Error(InvalidID); GlobalVariable *FwdRef = RefList[i].second; FwdRef->replaceAllUsesWith(BlockAddress::get(F, FunctionBBs[BlockIdx])); @@ -3012,7 +3046,7 @@ OutOfRecordLoop: ValueList.shrinkTo(ModuleValueListSize); MDValueList.shrinkTo(ModuleMDValueListSize); std::vector<BasicBlock*>().swap(FunctionBBs); - return false; + return error_code::success(); } /// FindFunctionInStream - Find the function body in the bitcode stream @@ -3020,7 +3054,7 @@ bool BitcodeReader::FindFunctionInStream(Function *F, DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator) { while (DeferredFunctionInfoIterator->second == 0) { if (Stream.AtEndOfStream()) - return Error("Could not find Function in stream"); + return Error(CouldNotFindFunctionInStream); // ParseModule will parse the next body in the stream and set its // position in the DeferredFunctionInfo map. if (ParseModule(true)) return true; @@ -3056,8 +3090,9 @@ bool BitcodeReader::Materialize(GlobalValue *GV, std::string *ErrInfo) { // Move the bit stream to the saved position of the deferred function body. Stream.JumpToBit(DFII->second); - if (ParseFunctionBody(F)) { - if (ErrInfo) *ErrInfo = ErrorString; + if (error_code EC = ParseFunctionBody(F)) { + if (ErrInfo) + *ErrInfo = EC.message(); return true; } @@ -3138,35 +3173,36 @@ bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) { return false; } -bool BitcodeReader::InitStream() { - if (LazyStreamer) return InitLazyStream(); +error_code BitcodeReader::InitStream() { + if (LazyStreamer) + return InitLazyStream(); return InitStreamFromBuffer(); } -bool BitcodeReader::InitStreamFromBuffer() { +error_code BitcodeReader::InitStreamFromBuffer() { const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart(); const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); if (Buffer->getBufferSize() & 3) { if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd)) - return Error("Invalid bitcode signature"); + return Error(InvalidBitcodeSignature); else - return Error("Bitcode stream should be a multiple of 4 bytes in length"); + return Error(BitcodeStreamInvalidSize); } // If we have a wrapper header, parse it and ignore the non-bc file contents. // The magic number is 0x0B17C0DE stored in little endian. if (isBitcodeWrapper(BufPtr, BufEnd)) if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true)) - return Error("Invalid bitcode wrapper header"); + return Error(InvalidBitcodeWrapperHeader); StreamFile.reset(new BitstreamReader(BufPtr, BufEnd)); Stream.init(*StreamFile); - return false; + return error_code::success(); } -bool BitcodeReader::InitLazyStream() { +error_code BitcodeReader::InitLazyStream() { // Check and strip off the bitcode wrapper; BitstreamReader expects never to // see it. StreamingMemoryObject *Bytes = new StreamingMemoryObject(LazyStreamer); @@ -3175,10 +3211,10 @@ bool BitcodeReader::InitLazyStream() { unsigned char buf[16]; if (Bytes->readBytes(0, 16, buf) == -1) - return Error("Bitcode stream must be at least 16 bytes in length"); + return Error(BitcodeStreamInvalidSize); if (!isBitcode(buf, buf + 16)) - return Error("Invalid bitcode signature"); + return Error(InvalidBitcodeSignature); if (isBitcodeWrapper(buf, buf + 4)) { const unsigned char *bitcodeStart = buf; @@ -3187,7 +3223,63 @@ bool BitcodeReader::InitLazyStream() { Bytes->dropLeadingBytes(bitcodeStart - buf); Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart); } - return false; + return error_code::success(); +} + +namespace { +class BitcodeErrorCategoryType : public _do_message { + const char *name() const LLVM_OVERRIDE { + return "llvm.bitcode"; + } + std::string message(int IE) const LLVM_OVERRIDE { + BitcodeReader::ErrorType E = static_cast<BitcodeReader::ErrorType>(IE); + switch (E) { + case BitcodeReader::BitcodeStreamInvalidSize: + return "Bitcode stream length should be >= 16 bytes and a multiple of 4"; + case BitcodeReader::ConflictingMETADATA_KINDRecords: + return "Conflicting METADATA_KIND records"; + case BitcodeReader::CouldNotFindFunctionInStream: + return "Could not find function in stream"; + case BitcodeReader::ExpectedConstant: + return "Expected a constant"; + case BitcodeReader::InsufficientFunctionProtos: + return "Insufficient function protos"; + case BitcodeReader::InvalidBitcodeSignature: + return "Invalid bitcode signature"; + case BitcodeReader::InvalidBitcodeWrapperHeader: + return "Invalid bitcode wrapper header"; + case BitcodeReader::InvalidConstantReference: + return "Invalid ronstant reference"; + case BitcodeReader::InvalidID: + return "Invalid ID"; + case BitcodeReader::InvalidInstructionWithNoBB: + return "Invalid instruction with no BB"; + case BitcodeReader::InvalidRecord: + return "Invalid record"; + case BitcodeReader::InvalidTypeForValue: + return "Invalid type for value"; + case BitcodeReader::InvalidTYPETable: + return "Invalid TYPE table"; + case BitcodeReader::InvalidType: + return "Invalid type"; + case BitcodeReader::MalformedBlock: + return "Malformed block"; + case BitcodeReader::MalformedGlobalInitializerSet: + return "Malformed global initializer set"; + case BitcodeReader::InvalidMultipleBlocks: + return "Invalid multiple blocks"; + case BitcodeReader::NeverResolvedValueFoundInFunction: + return "Never resolved value found in function"; + case BitcodeReader::InvalidValue: + return "Invalid value"; + } + } +}; +} + +const error_category &BitcodeReader::BitcodeErrorCategory() { + static BitcodeErrorCategoryType O; + return O; } //===----------------------------------------------------------------------===// @@ -3202,9 +3294,9 @@ Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer, Module *M = new Module(Buffer->getBufferIdentifier(), Context); BitcodeReader *R = new BitcodeReader(Buffer, Context); M->setMaterializer(R); - if (R->ParseBitcodeInto(M)) { + if (error_code EC = R->ParseBitcodeInto(M)) { if (ErrMsg) - *ErrMsg = R->getErrorString(); + *ErrMsg = EC.message(); delete M; // Also deletes R. return 0; @@ -3225,9 +3317,9 @@ Module *llvm::getStreamedBitcodeModule(const std::string &name, Module *M = new Module(name, Context); BitcodeReader *R = new BitcodeReader(streamer, Context); M->setMaterializer(R); - if (R->ParseBitcodeInto(M)) { + if (error_code EC = R->ParseBitcodeInto(M)) { if (ErrMsg) - *ErrMsg = R->getErrorString(); + *ErrMsg = EC.message(); delete M; // Also deletes R. return 0; } @@ -3266,9 +3358,9 @@ std::string llvm::getBitcodeTargetTriple(MemoryBuffer *Buffer, R->setBufferOwned(false); std::string Triple(""); - if (R->ParseTriple(Triple)) + if (error_code EC = R->ParseTriple(Triple)) if (ErrMsg) - *ErrMsg = R->getErrorString(); + *ErrMsg = EC.message(); delete R; return Triple; diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index b284e8c..0a8bb01 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -21,6 +21,7 @@ #include "llvm/IR/Attributes.h" #include "llvm/IR/OperandTraits.h" #include "llvm/IR/Type.h" +#include "llvm/Support/system_error.h" #include "llvm/Support/ValueHandle.h" #include <vector> @@ -132,8 +133,6 @@ class BitcodeReader : public GVMaterializer { uint64_t NextUnreadBit; bool SeenValueSymbolTable; - const char *ErrorString; - std::vector<Type*> TypeList; BitcodeReaderValueList ValueList; BitcodeReaderMDValueList MDValueList; @@ -194,17 +193,46 @@ class BitcodeReader : public GVMaterializer { /// not need this flag. bool UseRelativeIDs; + static const error_category &BitcodeErrorCategory(); + public: + enum ErrorType { + BitcodeStreamInvalidSize, + ConflictingMETADATA_KINDRecords, + CouldNotFindFunctionInStream, + ExpectedConstant, + InsufficientFunctionProtos, + InvalidBitcodeSignature, + InvalidBitcodeWrapperHeader, + InvalidConstantReference, + InvalidID, // A read identifier is not found in the table it should be in. + InvalidInstructionWithNoBB, + InvalidRecord, // A read record doesn't have the expected size or structure + InvalidTypeForValue, // Type read OK, but is invalid for its use + InvalidTYPETable, + InvalidType, // We were unable to read a type + MalformedBlock, // We are unable to advance in the stream. + MalformedGlobalInitializerSet, + InvalidMultipleBlocks, // We found multiple blocks of a kind that should + // have only one + NeverResolvedValueFoundInFunction, + InvalidValue // Invalid version, inst number, attr number, etc + }; + + error_code Error(ErrorType E) { + return error_code(E, BitcodeErrorCategory()); + } + explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C) : Context(C), TheModule(0), Buffer(buffer), BufferOwned(false), LazyStreamer(0), NextUnreadBit(0), SeenValueSymbolTable(false), - ErrorString(0), ValueList(C), MDValueList(C), + ValueList(C), MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false) { } explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C) : Context(C), TheModule(0), Buffer(0), BufferOwned(false), LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false), - ErrorString(0), ValueList(C), MDValueList(C), + ValueList(C), MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false) { } ~BitcodeReader() { @@ -225,19 +253,13 @@ public: virtual bool MaterializeModule(Module *M, std::string *ErrInfo = 0); virtual void Dematerialize(GlobalValue *GV); - bool Error(const char *Str) { - ErrorString = Str; - return true; - } - const char *getErrorString() const { return ErrorString; } - /// @brief Main interface to parsing a bitcode buffer. /// @returns true if an error occurred. - bool ParseBitcodeInto(Module *M); + error_code ParseBitcodeInto(Module *M); /// @brief Cheap mechanism to just extract module triple /// @returns true if an error occurred. - bool ParseTriple(std::string &Triple); + error_code ParseTriple(std::string &Triple); static uint64_t decodeSignRotatedValue(uint64_t V); @@ -324,26 +346,26 @@ private: return getFnValueByID(ValNo, Ty); } - bool ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind); - bool ParseModule(bool Resume); - bool ParseAttributeBlock(); - bool ParseAttributeGroupBlock(); - bool ParseTypeTable(); - bool ParseTypeTableBody(); - - bool ParseValueSymbolTable(); - bool ParseConstants(); - bool RememberAndSkipFunctionBody(); - bool ParseFunctionBody(Function *F); - bool GlobalCleanup(); - bool ResolveGlobalAndAliasInits(); - bool ParseMetadata(); - bool ParseMetadataAttachment(); - bool ParseModuleTriple(std::string &Triple); - bool ParseUseLists(); - bool InitStream(); - bool InitStreamFromBuffer(); - bool InitLazyStream(); + error_code ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind); + error_code ParseModule(bool Resume); + error_code ParseAttributeBlock(); + error_code ParseAttributeGroupBlock(); + error_code ParseTypeTable(); + error_code ParseTypeTableBody(); + + error_code ParseValueSymbolTable(); + error_code ParseConstants(); + error_code RememberAndSkipFunctionBody(); + error_code ParseFunctionBody(Function *F); + error_code GlobalCleanup(); + error_code ResolveGlobalAndAliasInits(); + error_code ParseMetadata(); + error_code ParseMetadataAttachment(); + error_code ParseModuleTriple(std::string &Triple); + error_code ParseUseLists(); + error_code InitStream(); + error_code InitStreamFromBuffer(); + error_code InitLazyStream(); bool FindFunctionInStream(Function *F, DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator); }; diff --git a/test/Bitcode/invalid.ll b/test/Bitcode/invalid.ll index 51d8cf2..1d4a82b 100644 --- a/test/Bitcode/invalid.ll +++ b/test/Bitcode/invalid.ll @@ -1,6 +1,6 @@ ; RUN: not llvm-dis < %s.bc 2>&1 | FileCheck %s -; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: Unknown attribute kind +; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: Invalid value ; invalid.ll.bc has an invalid attribute number. ; The test checks that LLVM reports the error and doesn't access freed memory diff --git a/test/Bitcode/null-type.ll b/test/Bitcode/null-type.ll index d01488c..a620fab 100644 --- a/test/Bitcode/null-type.ll +++ b/test/Bitcode/null-type.ll @@ -1,4 +1,4 @@ ; RUN: not llvm-dis < %s.bc 2>&1 | FileCheck %s ; PR8494 -; CHECK: Invalid MODULE_CODE_FUNCTION record +; CHECK: Invalid record |