diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 82dadb47210..2c9b1212b11 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -314,17 +314,10 @@ public: 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(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!"); diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index a36e131b4bc..d3db053c099 100644 --- a/unittests/IR/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -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));