Index: lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
index fa94733ef04fab95c98414bd97dc06e4b1e55837..5252584009d6419bad7b237b4173acf3068f8753 100644 |
--- a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
+++ b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
@@ -30,13 +30,18 @@ namespace { |
class PNaClABIVerifyFunctions : public FunctionPass { |
public: |
static char ID; |
- PNaClABIVerifyFunctions() : FunctionPass(ID), Errors(ErrorsString) {} |
+ PNaClABIVerifyFunctions() : FunctionPass(ID), Errors(ErrorsString), |
+ Strict(false), ErrorCount(0) {} |
bool runOnFunction(Function &F); |
virtual void print(raw_ostream &O, const Module *M) const; |
+ virtual void setStrict(bool Strict_) { Strict = Strict_; } |
+ virtual int getErrorCount() { return ErrorCount; } |
private: |
PNaClABITypeChecker TC; |
std::string ErrorsString; |
raw_string_ostream Errors; |
+ bool Strict; |
+ int ErrorCount; |
}; |
} // and anonymous namespace |
@@ -45,6 +50,7 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
// For now just start with new errors on each function; this may change |
// once we want to do something with them other than just calling print() |
ErrorsString.clear(); |
+ ErrorCount = 0; |
// TODO: only report one error per instruction |
for (Function::const_iterator FI = F.begin(), FE = F.end(); |
FI != FE; ++FI) { |
@@ -62,6 +68,7 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
Errors << "Function " + F.getName() + |
" has disallowed instruction: " + |
BBI->getOpcodeName() + "\n"; |
+ ErrorCount++; |
break; |
// Terminator instructions |
@@ -129,6 +136,7 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
Errors << "Function " + F.getName() + |
" has instruction with disallowed type: " + |
PNaClABITypeChecker::getTypeName(BBI->getType()) + "\n"; |
+ ErrorCount++; |
} |
// Check the instruction operands. Operands which are Instructions will |
@@ -141,10 +149,12 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
OI != OE; OI++) { |
if (isa<Constant>(OI) && !isa<GlobalValue>(OI)) { |
Type *T = TC.checkTypesInConstant(cast<Constant>(*OI)); |
- if (T) |
+ if (T) { |
Errors << "Function " + F.getName() + |
" has instruction operand with disallowed type: " + |
PNaClABITypeChecker::getTypeName(T) + "\n"; |
+ ErrorCount++; |
+ } |
} |
} |
@@ -153,15 +163,21 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
BBI->getAllMetadataOtherThanDebugLoc(MDForInst); |
for (unsigned i = 0, e = MDForInst.size(); i != e; i++) { |
Type *T = TC.checkTypesInMDNode(MDForInst[i].second); |
- if (T) |
+ if (T) { |
Errors << "Function " + F.getName() + |
" has instruction metadata containing disallowed type: " + |
PNaClABITypeChecker::getTypeName(T) + "\n"; |
+ ErrorCount++; |
+ } |
} |
} |
} |
Errors.flush(); |
+ if (Strict && ErrorCount > 0) { |
+ report_fatal_error("Function " + F.getName() + |
+ " is not valid PNaCl bitcode:\n" + ErrorsString); |
+ } |
return false; |
} |
@@ -175,6 +191,8 @@ char PNaClABIVerifyFunctions::ID = 0; |
static RegisterPass<PNaClABIVerifyFunctions> X("verify-pnaclabi-functions", |
"Verify functions for PNaCl", false, false); |
-FunctionPass *llvm::createPNaClABIVerifyFunctionsPass() { |
- return new PNaClABIVerifyFunctions(); |
+FunctionPass *llvm::createPNaClABIVerifyFunctionsPass(bool Strict) { |
+ PNaClABIVerifyFunctions *P = new PNaClABIVerifyFunctions(); |
+ P->setStrict(Strict); |
+ return P; |
} |