Skip to content

Commit

Permalink
[Verifier] Check parentage of GVs in dbg metadata
Browse files Browse the repository at this point in the history
Summary:
Before this the Verifier didn't complain if the GlobalVariable
referenced from a DIGlobalVariable was not in fact in the correct
module (it would crash while writing bitcode though). Fix this by
always checking parantage of GlobalValues while walking constant
expressions and changing the DIGlobalVariable visitor to also
visit the constant it contains.

Reviewers: rafael
Differential Revision: http://reviews.llvm.org/D16059

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257825 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Keno committed Jan 14, 2016
1 parent a8f3371 commit 508bcbe
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
11 changes: 9 additions & 2 deletions lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,7 @@ void Verifier::visitDIGlobalVariable(const DIGlobalVariable &N) {
Assert(isa<ConstantAsMetadata>(V) &&
!isa<Function>(cast<ConstantAsMetadata>(V)->getValue()),
"invalid global varaible ref", &N, V);
visitConstantExprsRecursively(cast<ConstantAsMetadata>(V)->getValue());
}
if (auto *Member = N.getRawStaticDataMemberDeclaration()) {
Assert(isa<DIDerivedType>(Member), "invalid static data member declaration",
Expand Down Expand Up @@ -1561,13 +1562,19 @@ void Verifier::visitConstantExprsRecursively(const Constant *EntryC) {
if (const auto *CE = dyn_cast<ConstantExpr>(C))
visitConstantExpr(CE);

if (const auto *GV = dyn_cast<GlobalValue>(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<Constant>(U);
if (!OpC)
continue;
if (isa<GlobalValue>(OpC))
continue; // Global values get visited separately.
if (!ConstantExprVisited.insert(OpC).second)
continue;
Stack.push_back(OpC);
Expand Down
24 changes: 23 additions & 1 deletion unittests/IR/VerifierTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -119,7 +120,28 @@ TEST(VerifierTest, CrossModuleRef) {
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!"));
}
}
}

0 comments on commit 508bcbe

Please sign in to comment.