Verifier: Add operand checks for MDLexicalBlock

Add operand checks for `MDLexicalBlock` and `MDLexicalBlockFile`.  Like
`MDLocalVariable` and `MDLocation`, these nodes always require a scope.

There was no test bitrot to fix here (just updated the serialization
tests in test/Assembler/mdlexicalblock.ll).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233561 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2015-03-30 16:37:48 +00:00
parent 0c251f74ef
commit d3ec0ca17e
11 changed files with 82 additions and 28 deletions

View File

@ -1129,7 +1129,12 @@ protected:
~MDLexicalBlockBase() {}
public:
Metadata *getScope() const { return getOperand(1); }
// FIXME: Remove this once MDScope::getFile() does the same.
MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
MDLocalScope *getScope() const { return cast<MDLocalScope>(getRawScope()); }
Metadata *getRawScope() const { return getOperand(1); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDLexicalBlockKind ||
@ -1150,6 +1155,15 @@ class MDLexicalBlock : public MDLexicalBlockBase {
Column(Column) {}
~MDLexicalBlock() {}
static MDLexicalBlock *getImpl(LLVMContext &Context, MDLocalScope *Scope,
MDFile *File, unsigned Line, unsigned Column,
StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, static_cast<Metadata *>(Scope),
static_cast<Metadata *>(File), Line, Column, Storage,
ShouldCreate);
}
static MDLexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Line, unsigned Column,
StorageType Storage, bool ShouldCreate = true);
@ -1160,6 +1174,9 @@ class MDLexicalBlock : public MDLexicalBlockBase {
}
public:
DEFINE_MDNODE_GET(MDLexicalBlock, (MDLocalScope * Scope, MDFile *File,
unsigned Line, unsigned Column),
(Scope, File, Line, Column))
DEFINE_MDNODE_GET(MDLexicalBlock, (Metadata * Scope, Metadata *File,
unsigned Line, unsigned Column),
(Scope, File, Line, Column))
@ -1186,6 +1203,15 @@ class MDLexicalBlockFile : public MDLexicalBlockBase {
Discriminator(Discriminator) {}
~MDLexicalBlockFile() {}
static MDLexicalBlockFile *getImpl(LLVMContext &Context, MDLocalScope *Scope,
MDFile *File, unsigned Discriminator,
StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, static_cast<Metadata *>(Scope),
static_cast<Metadata *>(File), Discriminator, Storage,
ShouldCreate);
}
static MDLexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Discriminator,
StorageType Storage,
@ -1197,6 +1223,9 @@ class MDLexicalBlockFile : public MDLexicalBlockBase {
}
public:
DEFINE_MDNODE_GET(MDLexicalBlockFile, (MDLocalScope * Scope, MDFile *File,
unsigned Discriminator),
(Scope, File, Discriminator))
DEFINE_MDNODE_GET(MDLexicalBlockFile,
(Metadata * Scope, Metadata *File, unsigned Discriminator),
(Scope, File, Discriminator))

View File

@ -3571,7 +3571,7 @@ bool LLParser::ParseMDSubprogram(MDNode *&Result, bool IsDistinct) {
/// ::= !MDLexicalBlock(scope: !0, file: !2, line: 7, column: 9)
bool LLParser::ParseMDLexicalBlock(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, ); \
REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
OPTIONAL(column, ColumnField, );
@ -3587,7 +3587,7 @@ bool LLParser::ParseMDLexicalBlock(MDNode *&Result, bool IsDistinct) {
/// ::= !MDLexicalBlockFile(scope: !0, file: !2, discriminator: 9)
bool LLParser::ParseMDLexicalBlockFile(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, ); \
REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(file, MDField, ); \
REQUIRED(discriminator, MDUnsignedField, (0, UINT32_MAX));
PARSE_MD_FIELDS();

View File

@ -1654,8 +1654,8 @@ static void writeMDLexicalBlock(raw_ostream &Out, const MDLexicalBlock *N,
const Module *Context) {
Out << "!MDLexicalBlock(";
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
Printer.printMetadata("file", N->getFile());
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
Printer.printInt("column", N->getColumn());
Out << ")";
@ -1668,8 +1668,8 @@ static void writeMDLexicalBlockFile(raw_ostream &Out,
const Module *Context) {
Out << "!MDLexicalBlockFile(";
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
Printer.printMetadata("file", N->getFile());
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("discriminator", N->getDiscriminator(),
/* ShouldSkipZero */ false);
Out << ")";

View File

@ -272,6 +272,7 @@ MDLexicalBlock *MDLexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Line,
unsigned Column, StorageType Storage,
bool ShouldCreate) {
assert(Scope && "Expected scope");
DEFINE_GETIMPL_LOOKUP(MDLexicalBlock, (Scope, File, Line, Column));
Metadata *Ops[] = {File, Scope};
DEFINE_GETIMPL_STORE(MDLexicalBlock, (Line, Column), Ops);
@ -282,6 +283,7 @@ MDLexicalBlockFile *MDLexicalBlockFile::getImpl(LLVMContext &Context,
unsigned Discriminator,
StorageType Storage,
bool ShouldCreate) {
assert(Scope && "Expected scope");
DEFINE_GETIMPL_LOOKUP(MDLexicalBlockFile, (Scope, File, Discriminator));
Metadata *Ops[] = {File, Scope};
DEFINE_GETIMPL_STORE(MDLexicalBlockFile, (Discriminator), Ops);

View File

@ -594,11 +594,11 @@ template <> struct MDNodeKeyImpl<MDLexicalBlock> {
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
: Scope(Scope), File(File), Line(Line), Column(Column) {}
MDNodeKeyImpl(const MDLexicalBlock *N)
: Scope(N->getScope()), File(N->getFile()), Line(N->getLine()),
: Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
Column(N->getColumn()) {}
bool isKeyOf(const MDLexicalBlock *RHS) const {
return Scope == RHS->getScope() && File == RHS->getFile() &&
return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
Line == RHS->getLine() && Column == RHS->getColumn();
}
unsigned getHashValue() const {
@ -614,11 +614,11 @@ template <> struct MDNodeKeyImpl<MDLexicalBlockFile> {
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
: Scope(Scope), File(File), Discriminator(Discriminator) {}
MDNodeKeyImpl(const MDLexicalBlockFile *N)
: Scope(N->getScope()), File(N->getFile()),
: Scope(N->getRawScope()), File(N->getRawFile()),
Discriminator(N->getDiscriminator()) {}
bool isKeyOf(const MDLexicalBlockFile *RHS) const {
return Scope == RHS->getScope() && File == RHS->getFile() &&
return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
Discriminator == RHS->getDiscriminator();
}
unsigned getHashValue() const {

View File

@ -302,6 +302,7 @@ private:
void visitMDScope(const MDScope &N);
void visitMDDerivedTypeBase(const MDDerivedTypeBase &N);
void visitMDVariable(const MDVariable &N);
void visitMDLexicalBlockBase(const MDLexicalBlockBase &N);
// InstVisitor overrides...
using InstVisitor<Verifier>::visit;
@ -871,12 +872,21 @@ void Verifier::visitMDSubprogram(const MDSubprogram &N) {
}
}
void Verifier::visitMDLexicalBlock(const MDLexicalBlock &N) {
void Verifier::visitMDLexicalBlockBase(const MDLexicalBlockBase &N) {
Assert(N.getTag() == dwarf::DW_TAG_lexical_block, "invalid tag", &N);
Assert(N.getRawScope() && isa<MDLocalScope>(N.getRawScope()),
"invalid local scope", &N, N.getRawScope());
}
void Verifier::visitMDLexicalBlock(const MDLexicalBlock &N) {
visitMDLexicalBlockBase(N);
Assert(N.getLine() || !N.getColumn(),
"cannot have column info without line info", &N);
}
void Verifier::visitMDLexicalBlockFile(const MDLexicalBlockFile &N) {
Assert(N.getTag() == dwarf::DW_TAG_lexical_block, "invalid tag", &N);
visitMDLexicalBlockBase(N);
}
void Verifier::visitMDNamespace(const MDNamespace &N) {

View File

@ -0,0 +1,4 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK: <stdin>:[[@LINE+1]]:29: error: 'scope' cannot be null
!0 = !MDLexicalBlock(scope: null)

View File

@ -0,0 +1,4 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK: <stdin>:[[@LINE+1]]:33: error: 'scope' cannot be null
!0 = !MDLexicalBlockFile(scope: null)

View File

@ -5,15 +5,15 @@
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9}
!0 = distinct !{}
!1 = distinct !{}
!1 = !MDSubprogram(name: "foo", scope: !2)
!2 = !MDFile(filename: "path/to/file", directory: "/path/to/dir")
; CHECK: !3 = !MDLexicalBlock(scope: !0, file: !2, line: 7, column: 35)
!3 = !MDLexicalBlock(scope: !0, file: !2, line: 7, column: 35)
; CHECK: !3 = !MDLexicalBlock(scope: !1, file: !2, line: 7, column: 35)
!3 = !MDLexicalBlock(scope: !1, file: !2, line: 7, column: 35)
; CHECK: !4 = !MDLexicalBlock(scope: !0)
!4 = !MDLexicalBlock(scope: !0)
!5 = !MDLexicalBlock(scope: !0, file: null, line: 0, column: 0)
; CHECK: !4 = !MDLexicalBlock(scope: !1)
!4 = !MDLexicalBlock(scope: !1)
!5 = !MDLexicalBlock(scope: !1, file: null, line: 0, column: 0)
; CHECK: !5 = !MDLexicalBlockFile(scope: !3, file: !2, discriminator: 0)
; CHECK: !6 = !MDLexicalBlockFile(scope: !3, file: !2, discriminator: 1)

View File

@ -299,7 +299,9 @@ TEST_F(IRBuilderTest, DIBuilder) {
false, true, 1, 0, true, F);
EXPECT_TRUE(SP.Verify());
AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
auto BadScope = DIB.createLexicalBlockFile(DIDescriptor(), File, 0);
auto BarSP = DIB.createFunction(CU, "bar", "", File, 1, Type, false, true, 1,
0, true, nullptr);
auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0);
I->setDebugLoc(DebugLoc::get(2, 0, BadScope));
EXPECT_FALSE(SP.Verify());
DIB.finalize();

View File

@ -1555,8 +1555,8 @@ TEST_F(MDSubprogramTest, replaceFunction) {
typedef MetadataTest MDLexicalBlockTest;
TEST_F(MDLexicalBlockTest, get) {
Metadata *Scope = MDTuple::getDistinct(Context, None);
Metadata *File = MDTuple::getDistinct(Context, None);
MDLocalScope *Scope = getSubprogram();
MDFile *File = getFile();
unsigned Line = 5;
unsigned Column = 8;
@ -1569,8 +1569,9 @@ TEST_F(MDLexicalBlockTest, get) {
EXPECT_EQ(Column, N->getColumn());
EXPECT_EQ(N, MDLexicalBlock::get(Context, Scope, File, Line, Column));
EXPECT_NE(N, MDLexicalBlock::get(Context, File, File, Line, Column));
EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, Scope, Line, Column));
EXPECT_NE(N,
MDLexicalBlock::get(Context, getSubprogram(), File, Line, Column));
EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, getFile(), Line, Column));
EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, File, Line + 1, Column));
EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, File, Line, Column + 1));
@ -1581,8 +1582,8 @@ TEST_F(MDLexicalBlockTest, get) {
typedef MetadataTest MDLexicalBlockFileTest;
TEST_F(MDLexicalBlockFileTest, get) {
Metadata *Scope = MDTuple::getDistinct(Context, None);
Metadata *File = MDTuple::getDistinct(Context, None);
MDLocalScope *Scope = getSubprogram();
MDFile *File = getFile();
unsigned Discriminator = 5;
auto *N = MDLexicalBlockFile::get(Context, Scope, File, Discriminator);
@ -1593,8 +1594,10 @@ TEST_F(MDLexicalBlockFileTest, get) {
EXPECT_EQ(Discriminator, N->getDiscriminator());
EXPECT_EQ(N, MDLexicalBlockFile::get(Context, Scope, File, Discriminator));
EXPECT_NE(N, MDLexicalBlockFile::get(Context, File, File, Discriminator));
EXPECT_NE(N, MDLexicalBlockFile::get(Context, Scope, Scope, Discriminator));
EXPECT_NE(N, MDLexicalBlockFile::get(Context, getSubprogram(), File,
Discriminator));
EXPECT_NE(N,
MDLexicalBlockFile::get(Context, Scope, getFile(), Discriminator));
EXPECT_NE(N,
MDLexicalBlockFile::get(Context, Scope, File, Discriminator + 1));