Skip to content

Commit

Permalink
Verifier: Simplify and fix issue where we were not verifying unmateri…
Browse files Browse the repository at this point in the history
…alized functions.

Arrange to call verify(Function &) on each function, followed by
verify(Module &), whether the verifier is being used from the pass or
from verifyModule(). As a side effect, this fixes an issue that caused
us not to call verify(Function &) on unmaterialized functions from
verifyModule().

Differential Revision: http://reviews.llvm.org/D21042

llvm-svn: 271956
  • Loading branch information
pcc committed Jun 6, 2016
1 parent 7e4e69a commit bb73817
Showing 2 changed files with 18 additions and 15 deletions.
28 changes: 13 additions & 15 deletions llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
@@ -314,17 +314,10 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
Context = &M.getContext();
Broken = false;

// Scan through, checking all of the external function's linkage now...
for (const Function &F : M) {
visitGlobalValue(F);

// Check to make sure function prototypes are okay.
if (F.isDeclaration()) {
visitFunction(F);
if (F.getIntrinsicID() == Intrinsic::experimental_deoptimize)
DeoptimizeDeclarations.push_back(&F);
}
}
// Collect all declarations of the llvm.experimental.deoptimize intrinsic.
for (const Function &F : M)
if (F.getIntrinsicID() == Intrinsic::experimental_deoptimize)
DeoptimizeDeclarations.push_back(&F);

// Now that we've visited every function, verify that we never asked to
// recover a frame index that wasn't escaped.
@@ -1866,6 +1859,8 @@ void Verifier::verifySiblingFuncletUnwinds() {
// visitFunction - Verify that a function is ok.
//
void Verifier::visitFunction(const Function &F) {
visitGlobalValue(F);

// Check function arguments.
FunctionType *FT = F.getFunctionType();
unsigned NumArgs = F.arg_size();
@@ -4427,7 +4422,6 @@ void Verifier::verifyDeoptimizeCallingConvs() {

bool llvm::verifyFunction(const Function &f, raw_ostream *OS) {
Function &F = const_cast<Function &>(f);
assert(!F.isDeclaration() && "Cannot verify external functions");

// Don't use a raw_null_ostream. Printing IR is expensive.
Verifier V(OS, /*ShouldTreatBrokenDebugInfoAsError=*/true);
@@ -4444,8 +4438,7 @@ bool llvm::verifyModule(const Module &M, raw_ostream *OS,

bool Broken = false;
for (const Function &F : M)
if (!F.isDeclaration() && !F.isMaterializable())
Broken |= !V.verify(F);
Broken |= !V.verify(F);

Broken |= !V.verify(M);
if (BrokenDebugInfo)
@@ -4482,7 +4475,12 @@ struct VerifierLegacyPass : public FunctionPass {
}

bool doFinalization(Module &M) override {
bool HasErrors = !V.verify(M);
bool HasErrors = false;
for (Function &F : M)
if (F.isDeclaration())
HasErrors |= !V.verify(F);

HasErrors |= !V.verify(M);
if (FatalErrors) {
if (HasErrors)
report_fatal_error("Broken module found, compilation aborted!");
5 changes: 5 additions & 0 deletions llvm/unittests/IR/MetadataTest.cpp
Original file line number Diff line number Diff line change
@@ -2253,7 +2253,12 @@ TEST_F(FunctionAttachmentTest, Verifier) {
// be verified directly, so check that the module fails to verify).
EXPECT_TRUE(verifyModule(*F->getParent()));

// Nor can materializable functions.
F->setIsMaterializable(true);
EXPECT_TRUE(verifyModule(*F->getParent()));

// Functions with a body can.
F->setIsMaterializable(false);
(void)new UnreachableInst(Context, BasicBlock::Create(Context, "bb", F));
EXPECT_FALSE(verifyModule(*F->getParent()));
EXPECT_FALSE(verifyFunction(*F));

0 comments on commit bb73817

Please sign in to comment.