Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(578)

Unified Diff: lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp

Issue 770853002: Fix error reporting in the PNaCl bitcode reader. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Fix typo. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h ('k') | lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
diff --git a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
index 0d6f818d6bcef2d9cdb3269590556e7be1af64d8..ab3868e3fa7d54666f4cc10eaf9badac8f481b37 100644
--- a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
+++ b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
@@ -116,6 +116,48 @@ bool NaClBitcodeReaderValueList::createValueFwdRef(unsigned Idx, Type *Ty) {
return false;
}
+namespace {
+class NaClBitcodeErrorCategoryType : public std::error_category {
+ const char *name() const LLVM_NOEXCEPT override {
+ return "pnacl.bitcode";
+ }
+ std::string message(int IndexError) const override {
+ switch(static_cast<NaClBitcodeReader::ErrorType>(IndexError)) {
+ case NaClBitcodeReader::CouldNotFindFunctionInStream:
+ return "Unable to find function in bitcode stream.";
+ case NaClBitcodeReader::InsufficientFunctionProtos:
+ return "Insufficient function protos";
+ case NaClBitcodeReader::InvalidBitstream:
+ return "Error in bitstream format";
+ case NaClBitcodeReader::InvalidConstantReference:
+ return "Bad constant reference";
+ case NaClBitcodeReader::InvalidInstructionWithNoBB:
+ return "No basic block for instruction";
+ case NaClBitcodeReader::InvalidMultipleBlocks:
+ return "Multiple blocks for a kind of block that should have only one";
+ case NaClBitcodeReader::InvalidRecord:
+ return "Record doesn't have expected size or structure";
+ case NaClBitcodeReader::InvalidSkippedBlock:
+ return "Unable to skip unknown block in bitcode file";
+ case NaClBitcodeReader::InvalidType:
+ return "Invalid type in record";
+ case NaClBitcodeReader::InvalidTypeForValue:
+ return "Type of value in record incorrect";
+ case NaClBitcodeReader::InvalidValue:
+ return "Invalid value in record";
+ case NaClBitcodeReader::MalformedBlock:
+ return "Malformed block. Unable to advance over block";
+ }
+ llvm_unreachable("Unknown error type!");
+ }
+};
+} // end of anonomous namespace.
+
+const std::error_category &NaClBitcodeReader::BitcodeErrorCategory() {
+ static NaClBitcodeErrorCategoryType ErrCat;
+ return ErrCat;
+}
+
Type *NaClBitcodeReader::getTypeByID(unsigned ID) {
// The type table size is always specified correctly.
if (ID >= TypeList.size())
@@ -135,20 +177,27 @@ Type *NaClBitcodeReader::getTypeByID(unsigned ID) {
//===----------------------------------------------------------------------===//
-bool NaClBitcodeReader::ParseTypeTable() {
+std::error_code NaClBitcodeReader::Error(ErrorType E,
+ const std::string &Message) const {
+ if (Verbose)
+ *Verbose << "Error: " << Message << "\n";
+ return Error(E);
+}
+
+std::error_code NaClBitcodeReader::ParseTypeTable() {
DEBUG(dbgs() << "-> ParseTypeTable\n");
if (Stream.EnterSubBlock(naclbitc::TYPE_BLOCK_ID_NEW))
- return Error("Malformed block record");
+ return Error(InvalidRecord, "Malformed block record");
- bool result = ParseTypeTableBody();
+ std::error_code result = ParseTypeTableBody();
if (!result)
DEBUG(dbgs() << "<- ParseTypeTable\n");
return result;
}
-bool NaClBitcodeReader::ParseTypeTableBody() {
+std::error_code NaClBitcodeReader::ParseTypeTableBody() {
if (!TypeList.empty())
- return Error("Multiple TYPE_BLOCKs found!");
+ return Error(InvalidMultipleBlocks, "Multiple TYPE_BLOCKs found!");
SmallVector<uint64_t, 64> Record;
unsigned NumRecords = 0;
@@ -160,12 +209,12 @@ bool NaClBitcodeReader::ParseTypeTableBody() {
switch (Entry.Kind) {
case NaClBitstreamEntry::SubBlock: // Handled for us already.
case NaClBitstreamEntry::Error:
- Error("Error in the type table block");
- return true;
+ return Error(MalformedBlock, "Error in the type table block");
case NaClBitstreamEntry::EndBlock:
if (NumRecords != TypeList.size())
- return Error("Invalid type forward reference in TYPE_BLOCK");
- return false;
+ return Error(MalformedBlock,
+ "Invalid type forward reference in TYPE_BLOCK");
+ return std::error_code();
case NaClBitstreamEntry::Record:
// The interesting case.
break;
@@ -181,46 +230,46 @@ bool NaClBitcodeReader::ParseTypeTableBody() {
raw_string_ostream StrM(Message);
StrM << "Unknown type code in type table: " << TypeCode;
StrM.flush();
- return Error(Message);
+ return Error(InvalidValue, Message);
}
case naclbitc::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, "Invalid TYPE_CODE_NUMENTRY record");
TypeList.resize(Record[0]);
// No type was defined, skip the checks that follow the switch.
continue;
case naclbitc::TYPE_CODE_VOID: // VOID
if (Record.size() != 0)
- return Error("Invalid TYPE_CODE_VOID record");
+ return Error(InvalidRecord, "Invalid TYPE_CODE_VOID record");
ResultTy = Type::getVoidTy(Context);
break;
case naclbitc::TYPE_CODE_FLOAT: // FLOAT
if (Record.size() != 0)
- return Error("Invalid TYPE_CODE_FLOAT record");
+ return Error(InvalidRecord, "Invalid TYPE_CODE_FLOAT record");
ResultTy = Type::getFloatTy(Context);
break;
case naclbitc::TYPE_CODE_DOUBLE: // DOUBLE
if (Record.size() != 0)
- return Error("Invalid TYPE_CODE_DOUBLE record");
+ return Error(InvalidRecord, "Invalid TYPE_CODE_DOUBLE record");
ResultTy = Type::getDoubleTy(Context);
break;
case naclbitc::TYPE_CODE_INTEGER: // INTEGER: [width]
if (Record.size() != 1)
- return Error("Invalid TYPE_CODE_INTEGER record");
+ return Error(InvalidRecord, "Invalid TYPE_CODE_INTEGER record");
ResultTy = IntegerType::get(Context, Record[0]);
break;
case naclbitc::TYPE_CODE_FUNCTION: {
// FUNCTION: [vararg, retty, paramty x N]
if (Record.size() < 2)
- return Error("Invalid TYPE_CODE_FUNCTION record");
+ return Error(InvalidRecord, "Invalid TYPE_CODE_FUNCTION record");
SmallVector<Type *, 8> ArgTys;
for (unsigned i = 2, e = Record.size(); i != e; ++i) {
if (Type *T = getTypeByID(Record[i]))
@@ -231,28 +280,29 @@ bool NaClBitcodeReader::ParseTypeTableBody() {
ResultTy = getTypeByID(Record[1]);
if (ResultTy == 0 || ArgTys.size() < Record.size() - 2)
- return Error("invalid type in function type");
+ return Error(InvalidType, "invalid type in function type");
ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
break;
}
case naclbitc::TYPE_CODE_VECTOR: { // VECTOR: [numelts, eltty]
if (Record.size() != 2)
- return Error("Invalid VECTOR type record");
+ return Error(InvalidRecord, "Invalid VECTOR type record");
if ((ResultTy = getTypeByID(Record[1])))
ResultTy = VectorType::get(ResultTy, Record[0]);
else
- return Error("invalid type in vector type");
+ return Error(InvalidType, "invalid type in vector type");
break;
}
}
if (NumRecords >= TypeList.size())
- return Error("invalid TYPE table");
+ return Error(MalformedBlock, "invalid TYPE table");
assert(ResultTy && "Didn't read a type?");
assert(TypeList[NumRecords] == 0 && "Already read type?");
TypeList[NumRecords++] = ResultTy;
}
+ return std::error_code();
}
namespace {
@@ -310,7 +360,7 @@ public:
NumGlobals(0),
StartBit(Stream.GetCurrentBitNo()) {}
- bool GenerateGlobalVarsPass() {
+ std::error_code GenerateGlobalVarsPass() {
InitPass();
// The type for the initializer of the global variable.
@@ -327,11 +377,13 @@ public:
switch (Entry.Kind) {
case NaClBitstreamEntry::SubBlock:
case NaClBitstreamEntry::Error:
- return Reader.Error("Error in the global vars block");
+ return Reader.Error(NaClBitcodeReader::MalformedBlock,
+ "Error in the global vars block");
case NaClBitstreamEntry::EndBlock:
if (ProcessingGlobal || NumGlobals != (NextValueNo - FirstValueNo))
- return Reader.Error("Error in the global vars block");
- return false;
+ return Reader.Error(NaClBitcodeReader::MalformedBlock,
+ "Error in the global vars block");
+ return std::error_code();
case NaClBitstreamEntry::Record:
// The interesting case.
break;
@@ -341,11 +393,14 @@ public:
Record.clear();
unsigned Bitcode = Stream.readRecord(Entry.ID, Record);
switch (Bitcode) {
- default: return Reader.Error("Unknown global variable entry");
+ default:
+ return Reader.Error(NaClBitcodeReader::InvalidValue,
+ "Unknown global variable entry");
case naclbitc::GLOBALVAR_VAR:
// Start the definition of a global variable.
if (ProcessingGlobal || Record.size() != 2)
- return Reader.Error("Bad GLOBALVAR_VAR record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Bad GLOBALVAR_VAR record");
ProcessingGlobal = true;
VarAlignment = (1 << Record[0]) >> 1;
VarIsConstant = Record[1] != 0;
@@ -358,13 +413,15 @@ public:
// Record[0].
if (!ProcessingGlobal || !VarType.empty() ||
VarInitializersNeeded != 1 || Record.size() != 1)
- return Reader.Error("Bad GLOBALVAR_COMPOUND record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Bad GLOBALVAR_COMPOUND record");
VarInitializersNeeded = Record[0];
break;
case naclbitc::GLOBALVAR_ZEROFILL: {
// Define a type that defines a sequence of zero-filled bytes.
if (!ProcessingGlobal || Record.size() != 1)
- return Reader.Error("Bad GLOBALVAR_ZEROFILL record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Bad GLOBALVAR_ZEROFILL record");
VarType.push_back(ArrayType::get(
Type::getInt8Ty(Context), Record[0]));
break;
@@ -372,7 +429,8 @@ public:
case naclbitc::GLOBALVAR_DATA: {
// Defines a type defined by a sequence of byte values.
if (!ProcessingGlobal || Record.size() < 1)
- return Reader.Error("Bad GLOBALVAR_DATA record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Bad GLOBALVAR_DATA record");
VarType.push_back(ArrayType::get(
Type::getInt8Ty(Context), Record.size()));
break;
@@ -380,13 +438,15 @@ public:
case naclbitc::GLOBALVAR_RELOC: {
// Define a relocation initializer type.
if (!ProcessingGlobal || Record.size() < 1 || Record.size() > 2)
- return Reader.Error("Bad GLOBALVAR_RELOC record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Bad GLOBALVAR_RELOC record");
VarType.push_back(IntegerType::get(Context, 32));
break;
}
case naclbitc::GLOBALVAR_COUNT:
if (Record.size() != 1 || NumGlobals != 0)
- return Reader.Error("Invalid global count record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Invalid global count record");
NumGlobals = Record[0];
break;
}
@@ -399,6 +459,7 @@ public:
switch (VarType.size()) {
case 0:
return Reader.Error(
+ NaClBitcodeReader::InvalidRecord,
"No initializer for global variable in global vars block");
case 1:
Ty = VarType[0];
@@ -419,9 +480,10 @@ public:
VarInitializersNeeded = 0;
VarType.clear();
}
+ return std::error_code();
}
- bool GenerateGlobalVarInitsPass() {
+ std::error_code GenerateGlobalVarInitsPass() {
InitPass();
// The initializer for the global variable.
SmallVector<Constant *, 10> VarInit;
@@ -432,11 +494,13 @@ public:
switch (Entry.Kind) {
case NaClBitstreamEntry::SubBlock:
case NaClBitstreamEntry::Error:
- return Reader.Error("Error in the global vars block");
+ return Reader.Error(NaClBitcodeReader::MalformedBlock,
+ "Error in the global vars block");
case NaClBitstreamEntry::EndBlock:
if (ProcessingGlobal || NumGlobals != (NextValueNo - FirstValueNo))
- return Reader.Error("Error in the global vars block");
- return false;
+ return Reader.Error(NaClBitcodeReader::MalformedBlock,
+ "Error in the global vars block");
+ return std::error_code();
case NaClBitstreamEntry::Record:
if (Entry.ID == naclbitc::DEFINE_ABBREV) {
Stream.SkipAbbrevRecord();
@@ -445,14 +509,17 @@ public:
// The interesting case.
break;
default:
- return Reader.Error("Unexpected record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Unexpected record");
}
// Read a record.
Record.clear();
unsigned Bitcode = Stream.readRecord(Entry.ID, Record);
switch (Bitcode) {
- default: return Reader.Error("Unknown global variable entry 2");
+ default:
+ return Reader.Error(NaClBitcodeReader::InvalidValue,
+ "Unknown global variable entry 2");
case naclbitc::GLOBALVAR_VAR:
// Start the definition of a global variable.
ProcessingGlobal = true;
@@ -465,13 +532,15 @@ public:
// Record[0].
if (!ProcessingGlobal || !VarInit.empty() ||
VarInitializersNeeded != 1 || Record.size() != 1)
- return Reader.Error("Bad GLOBALVAR_COMPOUND record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Bad GLOBALVAR_COMPOUND record");
VarInitializersNeeded = Record[0];
break;
case naclbitc::GLOBALVAR_ZEROFILL: {
// Define an initializer that defines a sequence of zero-filled bytes.
if (!ProcessingGlobal || Record.size() != 1)
- return Reader.Error("Bad GLOBALVAR_ZEROFILL record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Bad GLOBALVAR_ZEROFILL record");
Type *Ty = ArrayType::get(Type::getInt8Ty(Context),
Record[0]);
Constant *Zero = ConstantAggregateZero::get(Ty);
@@ -481,7 +550,8 @@ public:
case naclbitc::GLOBALVAR_DATA: {
// Defines an initializer defined by a sequence of byte values.
if (!ProcessingGlobal || Record.size() < 1)
- return Reader.Error("Bad GLOBALVAR_DATA record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Bad GLOBALVAR_DATA record");
unsigned Size = Record.size();
uint8_t *Buf = new uint8_t[Size];
assert(Buf);
@@ -496,7 +566,8 @@ public:
case naclbitc::GLOBALVAR_RELOC: {
// Define a relocation initializer.
if (!ProcessingGlobal || Record.size() < 1 || Record.size() > 2)
- return Reader.Error("Bad GLOBALVAR_RELOC record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Bad GLOBALVAR_RELOC record");
Constant *BaseVal = cast<Constant>(ValueList[Record[0]]);
Type *IntPtrType = IntegerType::get(Context, 32);
Constant *Val = ConstantExpr::getPtrToInt(BaseVal, IntPtrType);
@@ -510,7 +581,8 @@ public:
}
case naclbitc::GLOBALVAR_COUNT:
if (Record.size() != 1)
- return Reader.Error("Invalid global count record");
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
+ "Invalid global count record");
// Note: NumGlobals should have been set in GenerateGlobalVarsPass.
// Fail if methods are called in wrong order.
assert(NumGlobals == Record[0]);
@@ -524,7 +596,7 @@ public:
Constant *Init = 0;
switch (VarInit.size()) {
case 0:
- return Reader.Error(
+ return Reader.Error(NaClBitcodeReader::InvalidRecord,
"No initializer for global variable in global vars block");
case 1:
Init = VarInit[0];
@@ -539,24 +611,26 @@ public:
VarInitializersNeeded = 0;
VarInit.clear();
}
+ return std::error_code();
}
};
} // End anonymous namespace.
-bool NaClBitcodeReader::ParseGlobalVars() {
+std::error_code NaClBitcodeReader::ParseGlobalVars() {
if (Stream.EnterSubBlock(naclbitc::GLOBALVAR_BLOCK_ID))
- return Error("Malformed block record");
+ return Error(InvalidRecord, "Malformed block record");
ParseGlobalsHandler PassHandler(*this, ValueList, Stream, Context, TheModule);
- if (PassHandler.GenerateGlobalVarsPass()) return true;
+ if (std::error_code EC = PassHandler.GenerateGlobalVarsPass())
+ return EC;
return PassHandler.GenerateGlobalVarInitsPass();
}
-bool NaClBitcodeReader::ParseValueSymbolTable() {
+std::error_code NaClBitcodeReader::ParseValueSymbolTable() {
DEBUG(dbgs() << "-> ParseValueSymbolTable\n");
if (Stream.EnterSubBlock(naclbitc::VALUE_SYMTAB_BLOCK_ID))
- return Error("Malformed block record");
+ return Error(InvalidRecord, "Malformed block record");
SmallVector<uint64_t, 64> Record;
@@ -568,10 +642,10 @@ bool NaClBitcodeReader::ParseValueSymbolTable() {
switch (Entry.Kind) {
case NaClBitstreamEntry::SubBlock: // Handled for us already.
case NaClBitstreamEntry::Error:
- return Error("malformed value symbol table block");
+ return Error(MalformedBlock, "malformed value symbol table block");
case NaClBitstreamEntry::EndBlock:
DEBUG(dbgs() << "<- ParseValueSymbolTable\n");
- return false;
+ return std::error_code();
case NaClBitstreamEntry::Record:
// The interesting case.
break;
@@ -584,10 +658,10 @@ bool NaClBitcodeReader::ParseValueSymbolTable() {
break;
case naclbitc::VST_CODE_ENTRY: { // VST_ENTRY: [valueid, namechar x N]
if (ConvertToString(Record, 1, ValueName))
- return Error("Invalid VST_ENTRY record");
+ return Error(InvalidRecord, "Invalid VST_ENTRY record");
unsigned ValueID = Record[0];
if (ValueID >= ValueList.size())
- return Error("Invalid Value ID in VST_ENTRY record");
+ return Error(InvalidValue, "Invalid Value ID in VST_ENTRY record");
Value *V = ValueList[ValueID];
V->setName(StringRef(ValueName.data(), ValueName.size()));
@@ -596,10 +670,10 @@ bool NaClBitcodeReader::ParseValueSymbolTable() {
}
case naclbitc::VST_CODE_BBENTRY: {
if (ConvertToString(Record, 1, ValueName))
- return Error("Invalid VST_BBENTRY record");
+ return Error(InvalidRecord, "Invalid VST_BBENTRY record");
BasicBlock *BB = getBasicBlock(Record[0]);
if (BB == 0)
- return Error("Invalid BB ID in VST_BBENTRY record");
+ return Error(InvalidValue, "Invalid BB ID in VST_BBENTRY record");
BB->setName(StringRef(ValueName.data(), ValueName.size()));
ValueName.clear();
@@ -609,10 +683,10 @@ bool NaClBitcodeReader::ParseValueSymbolTable() {
}
}
-bool NaClBitcodeReader::ParseConstants() {
+std::error_code NaClBitcodeReader::ParseConstants() {
DEBUG(dbgs() << "-> ParseConstants\n");
if (Stream.EnterSubBlock(naclbitc::CONSTANTS_BLOCK_ID))
- return Error("Malformed block record");
+ return Error(InvalidRecord, "Malformed block record");
SmallVector<uint64_t, 64> Record;
@@ -625,12 +699,13 @@ bool NaClBitcodeReader::ParseConstants() {
switch (Entry.Kind) {
case NaClBitstreamEntry::SubBlock: // Handled for us already.
case NaClBitstreamEntry::Error:
- return Error("malformed block record in AST file");
+ return Error(MalformedBlock, "malformed block record in AST file");
case NaClBitstreamEntry::EndBlock:
if (NextCstNo != ValueList.size())
- return Error("Invalid constant reference!");
+ return Error(InvalidConstantReference,
+ "Invalid constant reference!");
DEBUG(dbgs() << "<- ParseConstants\n");
- return false;
+ return std::error_code();
case NaClBitstreamEntry::Record:
// The interesting case.
break;
@@ -646,26 +721,28 @@ bool NaClBitcodeReader::ParseConstants() {
raw_string_ostream StrM(Message);
StrM << "Invalid Constant code: " << BitCode;
StrM.flush();
- return Error(Message);
+ return Error(InvalidValue, Message);
}
case naclbitc::CST_CODE_UNDEF: // UNDEF
V = UndefValue::get(CurTy);
break;
case naclbitc::CST_CODE_SETTYPE: // SETTYPE: [typeid]
if (Record.empty())
- return Error("Malformed CST_SETTYPE record");
+ return Error(NaClBitcodeReader::InvalidRecord,
+ "Malformed CST_SETTYPE record");
if (Record[0] >= TypeList.size())
- return Error("Invalid Type ID in CST_SETTYPE record");
+ return Error(NaClBitcodeReader::InvalidType,
+ "Invalid Type ID in CST_SETTYPE record");
CurTy = TypeList[Record[0]];
continue; // Skip the ValueList manipulation.
case naclbitc::CST_CODE_INTEGER: // INTEGER: [intval]
if (!CurTy->isIntegerTy() || Record.empty())
- return Error("Invalid CST_INTEGER record");
+ return Error(InvalidRecord, "Invalid CST_INTEGER record");
V = ConstantInt::get(CurTy, NaClDecodeSignRotatedValue(Record[0]));
break;
case naclbitc::CST_CODE_FLOAT: { // FLOAT: [fpval]
if (Record.empty())
- return Error("Invalid FLOAT record");
+ return Error(NaClBitcodeReader::InvalidRecord, "Invalid FLOAT record");
if (CurTy->isFloatTy())
V = ConstantFP::get(Context, APFloat(APFloat::IEEEsingle,
APInt(32, (uint32_t)Record[0])));
@@ -673,7 +750,8 @@ bool NaClBitcodeReader::ParseConstants() {
V = ConstantFP::get(Context, APFloat(APFloat::IEEEdouble,
APInt(64, Record[0])));
else
- return Error("Unknown type for FLOAT record");
+ return Error(NaClBitcodeReader::InvalidRecord,
+ "Unknown type for FLOAT record");
break;
}
}
@@ -681,16 +759,18 @@ bool NaClBitcodeReader::ParseConstants() {
ValueList.AssignValue(V, NextCstNo);
++NextCstNo;
}
+ return std::error_code();
}
/// 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 NaClBitcodeReader::RememberAndSkipFunctionBody() {
+std::error_code NaClBitcodeReader::RememberAndSkipFunctionBody() {
DEBUG(dbgs() << "-> RememberAndSkipFunctionBody\n");
// Get the function we are talking about.
if (FunctionsWithBodies.empty())
- return Error("Insufficient function protos");
+ return Error(InsufficientFunctionProtos,
+ "Insufficient function protos");
Function *Fn = FunctionsWithBodies.back();
FunctionsWithBodies.pop_back();
@@ -701,12 +781,12 @@ bool NaClBitcodeReader::RememberAndSkipFunctionBody() {
// Skip over the function block for now.
if (Stream.SkipBlock())
- return Error("Malformed block record");
+ return Error(InvalidSkippedBlock, "Unable to skip function block.");
DEBUG(dbgs() << "<- RememberAndSkipFunctionBody\n");
- return false;
+ return std::error_code();
}
-bool NaClBitcodeReader::GlobalCleanup() {
+std::error_code NaClBitcodeReader::GlobalCleanup() {
// Look for intrinsic functions which need to be upgraded at some point
for (Module::iterator FI = TheModule->begin(), FE = TheModule->end();
FI != FE; ++FI) {
@@ -720,7 +800,7 @@ bool NaClBitcodeReader::GlobalCleanup() {
GI = TheModule->global_begin(), GE = TheModule->global_end();
GI != GE; ++GI)
UpgradeGlobalVariable(GI);
- return false;
+ return std::error_code();
}
FunctionType *NaClBitcodeReader::AddPointerTypesToIntrinsicType(
@@ -777,12 +857,12 @@ void NaClBitcodeReader::AddPointerTypesToIntrinsicParams() {
}
}
-bool NaClBitcodeReader::ParseModule(bool Resume) {
+std::error_code NaClBitcodeReader::ParseModule(bool Resume) {
DEBUG(dbgs() << "-> ParseModule\n");
if (Resume)
Stream.JumpToBit(NextUnreadBit);
else if (Stream.EnterSubBlock(naclbitc::MODULE_BLOCK_ID))
- return Error("Malformed block record");
+ return Error(InvalidRecord, "Malformed block record");
SmallVector<uint64_t, 64> Record;
@@ -792,8 +872,7 @@ bool NaClBitcodeReader::ParseModule(bool Resume) {
switch (Entry.Kind) {
case NaClBitstreamEntry::Error:
- Error("malformed module block");
- return true;
+ return Error(MalformedBlock, "malformed module block");
case NaClBitstreamEntry::EndBlock:
DEBUG(dbgs() << "<- ParseModule\n");
return GlobalCleanup();
@@ -804,23 +883,23 @@ bool NaClBitcodeReader::ParseModule(bool Resume) {
std::string Message;
raw_string_ostream StrM(Message);
StrM << "Unknown block ID: " << Entry.ID;
- return Error(StrM.str());
+ return Error(InvalidRecord, StrM.str());
}
case naclbitc::BLOCKINFO_BLOCK_ID:
if (Stream.ReadBlockInfoBlock(0))
- return Error("Malformed BlockInfoBlock");
+ return Error(MalformedBlock, "Malformed BlockInfoBlock");
break;
case naclbitc::TYPE_BLOCK_ID_NEW:
- if (ParseTypeTable())
- return true;
+ if (std::error_code EC = ParseTypeTable())
+ return EC;
break;
case naclbitc::GLOBALVAR_BLOCK_ID:
- if (ParseGlobalVars())
- return true;
+ if (std::error_code EC = ParseGlobalVars())
+ return EC;
break;
case naclbitc::VALUE_SYMTAB_BLOCK_ID:
- if (ParseValueSymbolTable())
- return true;
+ if (std::error_code EC = ParseValueSymbolTable())
+ return EC;
SeenValueSymbolTable = true;
// Now that we know the names of the intrinsics, we can add
// pointer types to the intrinsic declarations' types.
@@ -831,13 +910,13 @@ bool NaClBitcodeReader::ParseModule(bool Resume) {
// FunctionsWithBodies list.
if (!SeenFirstFunctionBody) {
std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end());
- if (GlobalCleanup())
- return true;
+ if (std::error_code EC = GlobalCleanup())
+ return EC;
SeenFirstFunctionBody = true;
}
- if (RememberAndSkipFunctionBody())
- return true;
+ if (std::error_code EC = RememberAndSkipFunctionBody())
+ return EC;
// For streaming bitcode, suspend parsing when we reach the function
// bodies. Subsequent materialization calls will resume it when
@@ -848,7 +927,7 @@ bool NaClBitcodeReader::ParseModule(bool Resume) {
if (LazyStreamer && SeenValueSymbolTable) {
NextUnreadBit = Stream.GetCurrentBitNo();
DEBUG(dbgs() << "<- ParseModule\n");
- return false;
+ return std::error_code();
}
break;
}
@@ -867,38 +946,41 @@ bool NaClBitcodeReader::ParseModule(bool Resume) {
raw_string_ostream StrM(Message);
StrM << "Invalid MODULE_CODE: " << Selector;
StrM.flush();
- return Error(Message);
+ return Error(InvalidValue, Message);
}
case naclbitc::MODULE_CODE_VERSION: { // VERSION: [version#]
if (Record.size() < 1)
- return Error("Malformed MODULE_CODE_VERSION");
+ return Error(InvalidRecord, "Malformed MODULE_CODE_VERSION");
// Only version #1 is supported for PNaCl. Version #0 is not supported.
unsigned module_version = Record[0];
if (module_version != 1)
- return Error("Unknown bitstream version!");
+ return Error(InvalidValue, "Unknown bitstream version!");
break;
}
// FUNCTION: [type, callingconv, isproto, linkage]
case naclbitc::MODULE_CODE_FUNCTION: {
if (Record.size() < 4)
- return Error("Invalid MODULE_CODE_FUNCTION record");
+ return Error(InvalidRecord, "Invalid MODULE_CODE_FUNCTION record");
Type *Ty = getTypeByID(Record[0]);
- if (!Ty) return Error("Invalid MODULE_CODE_FUNCTION record");
+ if (!Ty)
+ return Error(InvalidType, "Invalid MODULE_CODE_FUNCTION record");
FunctionType *FTy = dyn_cast<FunctionType>(Ty);
if (!FTy)
- return Error("Function not declared with a function type!");
+ return Error(InvalidType,
+ "Function not declared with a function type!");
Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage,
"", TheModule);
CallingConv::ID CallingConv;
if (!naclbitc::DecodeCallingConv(Record[1], CallingConv))
- return Error("PNaCl bitcode contains invalid calling conventions.");
+ return Error(InvalidValue,
+ "PNaCl bitcode contains invalid calling conventions.");
Func->setCallingConv(CallingConv);
bool isProto = Record[2];
GlobalValue::LinkageTypes Linkage;
if (!naclbitc::DecodeLinkage(Record[3], Linkage))
- return Error("Unknown linkage type");
+ return Error(InvalidValue, "Unknown linkage type");
Func->setLinkage(Linkage);
ValueList.push_back(Func);
@@ -913,13 +995,14 @@ bool NaClBitcodeReader::ParseModule(bool Resume) {
}
Record.clear();
}
+ return std::error_code();
}
const char *llvm::PNaClDataLayout =
"e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
"f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
-bool NaClBitcodeReader::ParseBitcodeInto(Module *M) {
+std::error_code NaClBitcodeReader::ParseBitcodeInto(Module *M) {
TheModule = 0;
// PNaCl does not support different DataLayouts in pexes, so we
@@ -931,63 +1014,67 @@ bool NaClBitcodeReader::ParseBitcodeInto(Module *M) {
// correct DataLayout if it is run on a pexe.
M->setDataLayout(PNaClDataLayout);
- if (InitStream()) return true; // InitSream will set the error string.
+ if (std::error_code EC = InitStream())
+ return EC;
// 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 std::error_code();
NaClBitstreamEntry Entry =
Stream.advance(NaClBitstreamCursor::AF_DontAutoprocessAbbrevs, 0);
switch (Entry.Kind) {
case NaClBitstreamEntry::Error:
- Error("malformed module file");
- return true;
+ return Error(MalformedBlock, "malformed module file");
case NaClBitstreamEntry::EndBlock:
- return false;
+ return std::error_code();
case NaClBitstreamEntry::SubBlock:
switch (Entry.ID) {
case naclbitc::BLOCKINFO_BLOCK_ID:
if (Stream.ReadBlockInfoBlock(0))
- return Error("Malformed BlockInfoBlock");
+ return Error(MalformedBlock, "Malformed BlockInfoBlock");
break;
case naclbitc::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,
+ "Multiple MODULE_BLOCKs in same stream");
TheModule = M;
- if (ParseModule(false))
- return true;
- if (LazyStreamer) return false;
+ if (std::error_code EC = ParseModule(false))
+ return EC;
+ if (LazyStreamer)
+ return std::error_code();
break;
default:
if (Stream.SkipBlock())
- return Error("Malformed block record");
+ return Error(InvalidSkippedBlock,
+ "Unable to skip unknown top-level block");
break;
}
continue;
case NaClBitstreamEntry::Record:
// There should be no records in the top-level of blocks.
- return Error("Invalid record at top-level");
+ return Error(InvalidRecord, "Invalid record at top-level");
}
}
}
// Returns true if error occured installing I into BB.
-bool NaClBitcodeReader::InstallInstruction(
+std::error_code NaClBitcodeReader::InstallInstruction(
BasicBlock *BB, Instruction *I) {
// Add instruction to end of current BB. If there is no current BB, reject
// this file.
if (BB == 0) {
delete I;
- return Error("Invalid instruction with no BB");
+ return Error(InvalidInstructionWithNoBB,
+ "Instruction with no BB, can't install");
}
BB->getInstList().push_back(I);
- return false;
+ return std::error_code();
}
CastInst *
@@ -1042,10 +1129,10 @@ Value *NaClBitcodeReader::ConvertOpToType(Value *Op, Type *T,
}
/// ParseFunctionBody - Lazily parse the specified function body block.
-bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
+std::error_code NaClBitcodeReader::ParseFunctionBody(Function *F) {
DEBUG(dbgs() << "-> ParseFunctionBody\n");
if (Stream.EnterSubBlock(naclbitc::FUNCTION_BLOCK_ID))
- return Error("Malformed block record");
+ return Error(InvalidRecord, "Malformed block record");
unsigned ModuleValueListSize = ValueList.size();
@@ -1064,28 +1151,28 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
switch (Entry.Kind) {
case NaClBitstreamEntry::Error:
- return Error("Bitcode error in function block");
+ return Error(MalformedBlock, "Bitcode error in function block");
case NaClBitstreamEntry::EndBlock:
goto OutOfRecordLoop;
case NaClBitstreamEntry::SubBlock:
switch (Entry.ID) {
default: // Skip unknown content.
- dbgs() << "default skip block\n";
if (Stream.SkipBlock())
- return Error("Malformed block record");
+ return Error(InvalidSkippedBlock,
+ "Unable to skip unknown block in function block");
break;
case naclbitc::CONSTANTS_BLOCK_ID:
- if (ParseConstants())
- return true;
+ if (std::error_code EC = ParseConstants())
+ return EC;
NextValueNo = ValueList.size();
break;
case naclbitc::VALUE_SYMTAB_BLOCK_ID:
if (PNaClAllowLocalSymbolTables) {
- if (ParseValueSymbolTable())
- return true;
+ if (std::error_code EC = ParseValueSymbolTable())
+ return EC;
} else {
- return Error("Local value symbol tables not allowed");
+ return Error(InvalidRecord, "Local value symbol tables not allowed");
}
break;
}
@@ -1109,12 +1196,12 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
StrM << " " << Record[I];
}
StrM << ">";
- return Error(StrM.str());
+ return Error(InvalidRecord, StrM.str());
}
case naclbitc::FUNC_CODE_DECLAREBLOCKS: // DECLAREBLOCKS: [nblocks]
if (Record.size() != 1 || Record[0] == 0)
- return Error("Invalid DECLAREBLOCKS record");
+ return Error(InvalidRecord, "Invalid DECLAREBLOCKS record");
// Create all the basic blocks for the function.
FunctionBBs.resize(Record[0]);
for (unsigned i = 0, e = FunctionBBs.size(); i != e; ++i) {
@@ -1133,14 +1220,14 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
if (popValue(Record, &OpNum, NextValueNo, &LHS) ||
popValue(Record, &OpNum, NextValueNo, &RHS) ||
OpNum+1 > Record.size())
- return Error("Invalid BINOP record");
+ return Error(InvalidRecord, "Invalid BINOP record");
LHS = ConvertOpToScalar(LHS, CurBBNo);
RHS = ConvertOpToScalar(RHS, CurBBNo);
Instruction::BinaryOps Opc;
if (!naclbitc::DecodeBinaryOpcode(Record[OpNum++], LHS->getType(), Opc))
- return Error("Invalid binary opcode in BINOP record");
+ return Error(InvalidValue, "Invalid binary opcode in BINOP record");
I = BinaryOperator::Create(Opc, LHS, RHS);
break;
}
@@ -1149,14 +1236,14 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
Value *Op;
if (popValue(Record, &OpNum, NextValueNo, &Op) ||
OpNum+2 != Record.size())
- return Error("Invalid CAST record: bad record size");
+ return Error(InvalidRecord, "Invalid CAST record: bad record size");
Type *ResTy = getTypeByID(Record[OpNum]);
if (ResTy == 0)
- return Error("Invalid CAST record: bad type ID");
+ return Error(InvalidType, "Invalid CAST record: bad type ID");
Instruction::CastOps Opc;
if (!naclbitc::DecodeCastOpcode(Record[OpNum+1], Opc)) {
- return Error("Invalid CAST record: bad opcode");
+ return Error(InvalidValue, "Invalid CAST record: bad opcode");
}
// If a ptrtoint cast was elided on the argument of the cast,
@@ -1187,7 +1274,7 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
popValue(Record, &OpNum, NextValueNo, &FalseVal) ||
popValue(Record, &OpNum, NextValueNo, &Cond) ||
OpNum != Record.size())
- return Error("Invalid SELECT record");
+ return Error(InvalidRecord, "Invalid SELECT record");
TrueVal = ConvertOpToScalar(TrueVal, CurBBNo);
FalseVal = ConvertOpToScalar(FalseVal, CurBBNo);
@@ -1197,11 +1284,12 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
dyn_cast<VectorType>(Cond->getType())) {
// expect <n x i1>
if (vector_type->getElementType() != Type::getInt1Ty(Context))
- return Error("Invalid SELECT vector condition type");
+ return Error(InvalidTypeForValue,
+ "Invalid SELECT vector condition type");
} else {
// expect i1
if (Cond->getType() != Type::getInt1Ty(Context))
- return Error("Invalid SELECT condition type");
+ return Error(InvalidTypeForValue, "Invalid SELECT condition type");
}
I = SelectInst::Create(Cond, TrueVal, FalseVal);
@@ -1213,11 +1301,11 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
Value *Vec, *Idx;
if (popValue(Record, &OpNum, NextValueNo, &Vec) ||
popValue(Record, &OpNum, NextValueNo, &Idx) || OpNum != Record.size())
- return Error("Invalid EXTRACTELEMENT record");
+ return Error(InvalidRecord, "Invalid EXTRACTELEMENT record");
// expect i32
if (Idx->getType() != Type::getInt32Ty(Context))
- return Error("Invalid EXTRACTELEMENT index type");
+ return Error(InvalidTypeForValue, "Invalid EXTRACTELEMENT index type");
I = ExtractElementInst::Create(Vec, Idx);
break;
@@ -1229,17 +1317,18 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
if (popValue(Record, &OpNum, NextValueNo, &Vec) ||
popValue(Record, &OpNum, NextValueNo, &Elt) ||
popValue(Record, &OpNum, NextValueNo, &Idx) || OpNum != Record.size())
- return Error("Invalid INSERTELEMENT record");
+ return Error(InvalidRecord, "Invalid INSERTELEMENT record");
// expect vector type
if (!isa<VectorType>(Vec->getType()))
- return Error("Invalid INSERTELEMENT vector type");
+ return Error(InvalidTypeForValue, "Invalid INSERTELEMENT vector type");
// match vector and element types
if (cast<VectorType>(Vec->getType())->getElementType() != Elt->getType())
- return Error("Mismatched INSERTELEMENT vector and element type");
+ return Error(InvalidTypeForValue,
+ "Mismatched INSERTELEMENT vector and element type");
// expect i32
if (Idx->getType() != Type::getInt32Ty(Context))
- return Error("Invalid INSERTELEMENT index type");
+ return Error(InvalidTypeForValue, "Invalid INSERTELEMENT index type");
I = InsertElementInst::Create(Vec, Elt, Idx);
break;
@@ -1253,7 +1342,7 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
if (popValue(Record, &OpNum, NextValueNo, &LHS) ||
popValue(Record, &OpNum, NextValueNo, &RHS) ||
OpNum+1 != Record.size())
- return Error("Invalid CMP record");
+ return Error(InvalidRecord, "Invalid CMP record");
LHS = ConvertOpToScalar(LHS, CurBBNo);
RHS = ConvertOpToScalar(RHS, CurBBNo);
@@ -1262,11 +1351,13 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
if (LHS->getType()->isFPOrFPVectorTy()) {
if (!naclbitc::DecodeFcmpPredicate(Record[OpNum], Predicate))
return Error(
+ InvalidValue,
"PNaCl bitcode contains invalid floating comparison predicate");
I = new FCmpInst(Predicate, LHS, RHS);
} else {
if (!naclbitc::DecodeIcmpPredicate(Record[OpNum], Predicate))
return Error(
+ InvalidValue,
"PNaCl bitcode contains invalid integer comparison predicate");
I = new ICmpInst(Predicate, LHS, RHS);
}
@@ -1284,19 +1375,19 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Op = NULL;
if (popValue(Record, &OpNum, NextValueNo, &Op))
- return Error("Invalid RET record");
+ return Error(InvalidRecord, "Invalid RET record");
if (OpNum != Record.size())
- return Error("Invalid RET record");
+ return Error(InvalidRecord, "Invalid RET record");
I = ReturnInst::Create(Context, ConvertOpToScalar(Op, CurBBNo));
break;
}
case naclbitc::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, "Invalid BR record");
BasicBlock *TrueDest = getBasicBlock(Record[0]);
if (TrueDest == 0)
- return Error("Invalid BR record");
+ return Error(InvalidRecord, "Invalid BR record");
if (Record.size() == 1) {
I = BranchInst::Create(TrueDest);
@@ -1305,23 +1396,24 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
BasicBlock *FalseDest = getBasicBlock(Record[1]);
Value *Cond = getValue(Record, 2, NextValueNo);
if (FalseDest == 0 || Cond == 0)
- return Error("Invalid BR record");
+ return Error(InvalidValue, "Invalid BR record");
I = BranchInst::Create(TrueDest, FalseDest, Cond);
}
break;
}
case naclbitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
if (Record.size() < 4)
- return Error("Invalid SWITCH record");
+ return Error(InvalidRecord, "Invalid SWITCH record");
Type *OpTy = getTypeByID(Record[0]);
unsigned ValueBitWidth = cast<IntegerType>(OpTy)->getBitWidth();
if (ValueBitWidth > 64)
- return Error("Wide integers are not supported in PNaCl bitcode");
+ return Error(InvalidValue,
+ "Wide integers are not supported in PNaCl bitcode");
Value *Cond = getValue(Record, 1, NextValueNo);
BasicBlock *Default = getBasicBlock(Record[2]);
if (OpTy == 0 || Cond == 0 || Default == 0)
- return Error("Invalid SWITCH record");
+ return Error(InvalidRecord, "Invalid SWITCH record");
unsigned NumCases = Record[3];
@@ -1336,7 +1428,8 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
unsigned NumItems = Record[CurIdx++];
bool isSingleNumber = Record[CurIdx++];
if (NumItems != 1 || !isSingleNumber)
- return Error("Case ranges are not supported in PNaCl bitcode");
+ return Error(InvalidRecord,
+ "Case ranges are not supported in PNaCl bitcode");
APInt CaseValue(ValueBitWidth,
NaClDecodeSignRotatedValue(Record[CurIdx++]));
@@ -1351,9 +1444,9 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
break;
case naclbitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...]
if (Record.size() < 1 || ((Record.size()-1)&1))
- return Error("Invalid PHI record");
+ return Error(InvalidRecord, "Invalid PHI record");
Type *Ty = getTypeByID(Record[0]);
- if (!Ty) return Error("Invalid PHI record");
+ if (!Ty) return Error(InvalidType, "Invalid PHI record");
PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2);
@@ -1365,7 +1458,8 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
V = getValueSigned(Record, 1+i, NextValueNo);
unsigned BBIndex = Record[2+i];
BasicBlock *BB = getBasicBlock(BBIndex);
- if (!V || !BB) return Error("Invalid PHI record");
+ if (!V || !BB)
+ return Error(InvalidValue, "Invalid PHI record");
if (Ty == IntPtrType) {
// Delay installing scalar casts until all instructions of
// the function are rendered. This guarantees that we insert
@@ -1381,11 +1475,11 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
case naclbitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [op, align]
if (Record.size() != 2)
- return Error("Invalid ALLOCA record");
+ return Error(InvalidRecord, "Invalid ALLOCA record");
Value *Size;
unsigned OpNum = 0;
if (popValue(Record, &OpNum, NextValueNo, &Size))
- return Error("Invalid ALLOCA record");
+ return Error(InvalidRecord, "Invalid ALLOCA record");
unsigned Align = Record[1];
I = new AllocaInst(Type::getInt8Ty(Context), Size, (1 << Align) >> 1);
break;
@@ -1396,14 +1490,15 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
Value *Op;
if (popValue(Record, &OpNum, NextValueNo, &Op) ||
Record.size() != 3)
- return Error("Invalid LOAD record");
+ return Error(InvalidRecord, "Invalid LOAD record");
// Add pointer cast to op.
Type *T = getTypeByID(Record[2]);
- if (T == 0)
- return Error("Invalid type for load instruction");
+ if (T == nullptr)
+ return Error(InvalidType, "Invalid type for load instruction");
Op = ConvertOpToType(Op, T->getPointerTo(), CurBBNo);
- if (Op == 0) return true;
+ if (Op == nullptr)
+ return Error(InvalidTypeForValue, "Can't convert cast to type");
I = new LoadInst(Op, "", false, (1 << Record[OpNum]) >> 1);
break;
}
@@ -1414,9 +1509,11 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
if (popValue(Record, &OpNum, NextValueNo, &Ptr) ||
popValue(Record, &OpNum, NextValueNo, &Val) ||
OpNum+1 != Record.size())
- return Error("Invalid STORE record");
+ return Error(InvalidRecord, "Invalid STORE record");
Val = ConvertOpToScalar(Val, CurBBNo);
Ptr = ConvertOpToType(Ptr, Val->getType()->getPointerTo(), CurBBNo);
+ if (Ptr == nullptr)
+ return Error(InvalidTypeForValue, "Can't convert cast to type");
I = new StoreInst(Val, Ptr, false, (1 << Record[OpNum]) >> 1);
break;
}
@@ -1427,14 +1524,14 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
if ((Record.size() < 2) ||
(BitCode == naclbitc::FUNC_CODE_INST_CALL_INDIRECT &&
Record.size() < 3))
- return Error("Invalid CALL record");
+ return Error(InvalidRecord, "Invalid CALL record");
unsigned CCInfo = Record[0];
unsigned OpNum = 1;
Value *Callee;
if (popValue(Record, &OpNum, NextValueNo, &Callee))
- return Error("Invalid CALL record");
+ return Error(InvalidRecord, "Invalid CALL record");
// Build function type for call.
FunctionType *FTy = 0;
@@ -1449,19 +1546,19 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
FTy = dyn_cast<FunctionType>(OpTy->getElementType());
}
if (FTy == 0)
- return Error("Invalid type for CALL record");
+ return Error(InvalidType, "Invalid type for CALL record");
}
unsigned NumParams = Record.size() - OpNum;
if (FTy && NumParams != FTy->getNumParams())
- return Error("Invalid CALL record");
+ return Error(InvalidRecord, "Invalid CALL record");
// Process call arguments.
SmallVector<Value*, 6> Args;
for (unsigned Index = 0; Index < NumParams; ++Index) {
Value *Arg;
if (popValue(Record, &OpNum, NextValueNo, &Arg))
- Error("Invalid argument in CALL record");
+ Error(InvalidValue, "Invalid argument in CALL record");
if (FTy) {
// Add a cast, to a pointer type if necessary, in case this
// is an intrinsic call that takes a pointer argument.
@@ -1486,7 +1583,8 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
I = CallInst::Create(Callee, Args);
CallingConv::ID CallingConv;
if (!naclbitc::DecodeCallingConv(CCInfo>>1, CallingConv))
- return Error("PNaCl bitcode contains invalid calling conventions.");
+ return Error(InvalidValue,
+ "PNaCl bitcode contains invalid calling conventions.");
cast<CallInst>(I)->setCallingConv(CallingConv);
cast<CallInst>(I)->setTailCall(CCInfo & 1);
break;
@@ -1495,12 +1593,12 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
// Build corresponding forward reference.
if (Record.size() != 2 ||
ValueList.createValueFwdRef(Record[0], getTypeByID(Record[1])))
- return Error("Invalid FORWARDTYPEREF record");
+ return Error(InvalidRecord, "Invalid FORWARDTYPEREF record");
continue;
}
- if (InstallInstruction(CurBB, I))
- return true;
+ if (std::error_code EC = InstallInstruction(CurBB, I))
+ return EC;
// If this was a terminator instruction, move to the next block.
if (isa<TerminatorInst>(I)) {
@@ -1550,7 +1648,7 @@ OutOfRecordLoop:
delete A;
}
}
- return Error("Never resolved value found in function!");
+ return Error(InvalidValue, "Never resolved value found in function!");
}
}
@@ -1558,20 +1656,23 @@ OutOfRecordLoop:
ValueList.shrinkTo(ModuleValueListSize);
FunctionBBs.clear();
DEBUG(dbgs() << "-> ParseFunctionBody\n");
- return false;
+ return std::error_code();
}
/// FindFunctionInStream - Find the function body in the bitcode stream
-bool NaClBitcodeReader::FindFunctionInStream(Function *F,
- DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator) {
+std::error_code NaClBitcodeReader::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,
+ "Could not find Function in stream");
// ParseModule will parse the next body in the stream and set its
// position in the DeferredFunctionInfo map.
- if (ParseModule(true)) return true;
+ if (std::error_code EC = ParseModule(true))
+ return EC;
}
- return false;
+ return std::error_code();
}
//===----------------------------------------------------------------------===//
@@ -1694,39 +1795,41 @@ std::error_code NaClBitcodeReader::MaterializeModule(Module *M) {
return std::error_code();
}
-bool NaClBitcodeReader::InitStream() {
- if (LazyStreamer) return InitLazyStream();
+std::error_code NaClBitcodeReader::InitStream() {
+ if (LazyStreamer)
+ return InitLazyStream();
return InitStreamFromBuffer();
}
-bool NaClBitcodeReader::InitStreamFromBuffer() {
+std::error_code NaClBitcodeReader::InitStreamFromBuffer() {
const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart();
const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
if (Buffer->getBufferSize() & 3)
- return Error("Bitcode stream should be a multiple of 4 bytes in length");
+ return Error(InvalidBitstream,
+ "Bitcode stream should be a multiple of 4 bytes in length");
if (Header.Read(BufPtr, BufEnd))
- return Error(Header.Unsupported());
+ return Error(InvalidBitstream, Header.Unsupported());
StreamFile.reset(new NaClBitstreamReader(BufPtr, BufEnd));
Stream.init(*StreamFile);
if (AcceptHeader())
- return Error(Header.Unsupported());
- return false;
+ return Error(InvalidBitstream, Header.Unsupported());
+ return std::error_code();
}
-bool NaClBitcodeReader::InitLazyStream() {
+std::error_code NaClBitcodeReader::InitLazyStream() {
if (Header.Read(LazyStreamer))
- return Error(Header.Unsupported());
+ return Error(InvalidBitstream, Header.Unsupported());
StreamFile.reset(new NaClBitstreamReader(LazyStreamer,
Header.getHeaderSize()));
Stream.init(*StreamFile);
if (AcceptHeader())
- return Error(Header.Unsupported());
- return false;
+ return Error(InvalidBitstream, Header.Unsupported());
+ return std::error_code();
}
//===----------------------------------------------------------------------===//
@@ -1735,20 +1838,17 @@ bool NaClBitcodeReader::InitLazyStream() {
/// getNaClLazyBitcodeModule - lazy function-at-a-time loading from a file.
///
-Module *llvm::getNaClLazyBitcodeModule(MemoryBuffer *Buffer,
- LLVMContext& Context,
- std::string *ErrMsg,
- bool AcceptSupportedOnly) {
+ErrorOr<Module *> llvm::getNaClLazyBitcodeModule(
+ MemoryBuffer *Buffer, LLVMContext& Context, raw_ostream *Verbose,
+ bool AcceptSupportedOnly) {
Module *M = new Module(Buffer->getBufferIdentifier(), Context);
NaClBitcodeReader *R =
- new NaClBitcodeReader(Buffer, Context, AcceptSupportedOnly);
+ new NaClBitcodeReader(Buffer, Context, Verbose, AcceptSupportedOnly);
M->setMaterializer(R);
- if (R->ParseBitcodeInto(M)) {
- if (ErrMsg)
- *ErrMsg = R->getErrorString();
-
+ if (std::error_code EC = R->ParseBitcodeInto(M)) {
+ R->releaseBuffer(); // Never take ownership on error.
delete M; // Also deletes R.
- return 0;
+ return EC;
}
return M;
@@ -1758,17 +1858,19 @@ Module *llvm::getNaClLazyBitcodeModule(MemoryBuffer *Buffer,
Module *llvm::getNaClStreamedBitcodeModule(const std::string &name,
StreamingMemoryObject *Streamer,
LLVMContext &Context,
+ raw_ostream *Verbose,
std::string *ErrMsg,
bool AcceptSupportedOnly) {
Module *M = new Module(name, Context);
NaClBitcodeReader *R =
- new NaClBitcodeReader(Streamer, Context, AcceptSupportedOnly);
+ new NaClBitcodeReader(Streamer, Context, Verbose,
+ AcceptSupportedOnly);
M->setMaterializer(R);
- if (R->ParseBitcodeInto(M)) {
+ if (std::error_code EC = R->ParseBitcodeInto(M)) {
if (ErrMsg)
- *ErrMsg = R->getErrorString();
+ *ErrMsg = EC.message();
delete M; // Also deletes R.
- return 0;
+ return nullptr;
}
return M;
@@ -1776,18 +1878,18 @@ Module *llvm::getNaClStreamedBitcodeModule(const std::string &name,
/// NaClParseBitcodeFile - Read the specified bitcode file, returning the module.
/// If an error occurs, return null and fill in *ErrMsg if non-null.
-Module *llvm::NaClParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
- std::string *ErrMsg,
- bool AcceptSupportedOnly){
- Module *M = getNaClLazyBitcodeModule(Buffer, Context, ErrMsg,
- AcceptSupportedOnly);
- if (!M) return 0;
-
+ErrorOr<Module *> llvm::NaClParseBitcodeFile(
+ MemoryBuffer *Buffer, LLVMContext& Context, raw_ostream *Verbose,
+ bool AcceptSupportedOnly){
+ ErrorOr<Module *> ModuleOrErr =
+ getNaClLazyBitcodeModule(Buffer, Context, Verbose, AcceptSupportedOnly);
+ if (!ModuleOrErr)
+ return ModuleOrErr;
+ Module *M = ModuleOrErr.get();
// Read in the entire module, and destroy the NaClBitcodeReader.
if (std::error_code EC = M->materializeAllPermanently()) {
- *ErrMsg = EC.message();
delete M;
- return 0;
+ return EC;
}
// TODO: Restore the use-lists to the in-memory state when the bitcode was
« no previous file with comments | « lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h ('k') | lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698