Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -1047,6 +1047,7 @@ Assert(isa(V) && !isa(cast(V)->getValue()), "invalid global varaible ref", &N, V); + visitConstantExprsRecursively(cast(V)->getValue()); } if (auto *Member = N.getRawStaticDataMemberDeclaration()) { Assert(isa(Member), "invalid static data member declaration", @@ -1511,13 +1512,19 @@ if (const auto *CE = dyn_cast(C)) visitConstantExpr(CE); + if (const auto *GV = dyn_cast(C)) { + // Global Values get visited separately, but we do need to make sure + // that the global value is in the correct module + Assert(GV->getParent() == M, "Referencing global in another module!", + EntryC, M, GV, GV->getParent()); + continue; + } + // Visit all sub-expressions. for (const Use &U : C->operands()) { const auto *OpC = dyn_cast(U); if (!OpC) continue; - if (isa(OpC)) - continue; // Global values get visited separately. if (!ConstantExprVisited.insert(OpC).second) continue; Stack.push_back(OpC); Index: unittests/IR/VerifierTest.cpp =================================================================== --- unittests/IR/VerifierTest.cpp +++ unittests/IR/VerifierTest.cpp @@ -9,6 +9,7 @@ #include "llvm/IR/Verifier.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DIBuilder.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalAlias.h" @@ -105,7 +106,28 @@ F3->eraseFromParent(); } +TEST(VerifierTest, CrossModuleMetadataRef) { + LLVMContext &C = getGlobalContext(); + Module M1("M1", C); + Module M2("M2", C); + GlobalVariable *newGV = + new GlobalVariable(M1, Type::getInt8Ty(C), false, + GlobalVariable::ExternalLinkage, NULL, "Some Global"); + + DIBuilder dbuilder(M2); + auto CU = dbuilder.createCompileUnit(dwarf::DW_LANG_Julia, "test.jl", ".", + "unittest", false, "", 0); + auto File = dbuilder.createFile("test.jl", "."); + auto Ty = dbuilder.createBasicType("Int8", 8, 8, dwarf::DW_ATE_signed); + dbuilder.createGlobalVariable(CU, "_SOME_GLOBAL", "_SOME_GLOBAL", File, 1, Ty, + false, newGV); + dbuilder.finalize(); - + std::string Error; + raw_string_ostream ErrorOS(Error); + EXPECT_TRUE(verifyModule(M2, &ErrorOS)); + EXPECT_TRUE(StringRef(ErrorOS.str()) + .startswith("Referencing global in another module!")); +} } }