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() {} ~MDLexicalBlockBase() {}
public: 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) { static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDLexicalBlockKind || return MD->getMetadataID() == MDLexicalBlockKind ||
@ -1150,6 +1155,15 @@ class MDLexicalBlock : public MDLexicalBlockBase {
Column(Column) {} Column(Column) {}
~MDLexicalBlock() {} ~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, static MDLexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Line, unsigned Column, Metadata *File, unsigned Line, unsigned Column,
StorageType Storage, bool ShouldCreate = true); StorageType Storage, bool ShouldCreate = true);
@ -1160,6 +1174,9 @@ class MDLexicalBlock : public MDLexicalBlockBase {
} }
public: 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, DEFINE_MDNODE_GET(MDLexicalBlock, (Metadata * Scope, Metadata *File,
unsigned Line, unsigned Column), unsigned Line, unsigned Column),
(Scope, File, Line, Column)) (Scope, File, Line, Column))
@ -1186,6 +1203,15 @@ class MDLexicalBlockFile : public MDLexicalBlockBase {
Discriminator(Discriminator) {} Discriminator(Discriminator) {}
~MDLexicalBlockFile() {} ~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, static MDLexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Discriminator, Metadata *File, unsigned Discriminator,
StorageType Storage, StorageType Storage,
@ -1197,6 +1223,9 @@ class MDLexicalBlockFile : public MDLexicalBlockBase {
} }
public: public:
DEFINE_MDNODE_GET(MDLexicalBlockFile, (MDLocalScope * Scope, MDFile *File,
unsigned Discriminator),
(Scope, File, Discriminator))
DEFINE_MDNODE_GET(MDLexicalBlockFile, DEFINE_MDNODE_GET(MDLexicalBlockFile,
(Metadata * Scope, Metadata *File, unsigned Discriminator), (Metadata * Scope, Metadata *File, unsigned Discriminator),
(Scope, File, 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) /// ::= !MDLexicalBlock(scope: !0, file: !2, line: 7, column: 9)
bool LLParser::ParseMDLexicalBlock(MDNode *&Result, bool IsDistinct) { bool LLParser::ParseMDLexicalBlock(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, ); \ REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(file, MDField, ); \ OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \ OPTIONAL(line, LineField, ); \
OPTIONAL(column, ColumnField, ); OPTIONAL(column, ColumnField, );
@ -3587,7 +3587,7 @@ bool LLParser::ParseMDLexicalBlock(MDNode *&Result, bool IsDistinct) {
/// ::= !MDLexicalBlockFile(scope: !0, file: !2, discriminator: 9) /// ::= !MDLexicalBlockFile(scope: !0, file: !2, discriminator: 9)
bool LLParser::ParseMDLexicalBlockFile(MDNode *&Result, bool IsDistinct) { bool LLParser::ParseMDLexicalBlockFile(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, ); \ REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(file, MDField, ); \ OPTIONAL(file, MDField, ); \
REQUIRED(discriminator, MDUnsignedField, (0, UINT32_MAX)); REQUIRED(discriminator, MDUnsignedField, (0, UINT32_MAX));
PARSE_MD_FIELDS(); PARSE_MD_FIELDS();

View File

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

View File

@ -272,6 +272,7 @@ MDLexicalBlock *MDLexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Line, Metadata *File, unsigned Line,
unsigned Column, StorageType Storage, unsigned Column, StorageType Storage,
bool ShouldCreate) { bool ShouldCreate) {
assert(Scope && "Expected scope");
DEFINE_GETIMPL_LOOKUP(MDLexicalBlock, (Scope, File, Line, Column)); DEFINE_GETIMPL_LOOKUP(MDLexicalBlock, (Scope, File, Line, Column));
Metadata *Ops[] = {File, Scope}; Metadata *Ops[] = {File, Scope};
DEFINE_GETIMPL_STORE(MDLexicalBlock, (Line, Column), Ops); DEFINE_GETIMPL_STORE(MDLexicalBlock, (Line, Column), Ops);
@ -282,6 +283,7 @@ MDLexicalBlockFile *MDLexicalBlockFile::getImpl(LLVMContext &Context,
unsigned Discriminator, unsigned Discriminator,
StorageType Storage, StorageType Storage,
bool ShouldCreate) { bool ShouldCreate) {
assert(Scope && "Expected scope");
DEFINE_GETIMPL_LOOKUP(MDLexicalBlockFile, (Scope, File, Discriminator)); DEFINE_GETIMPL_LOOKUP(MDLexicalBlockFile, (Scope, File, Discriminator));
Metadata *Ops[] = {File, Scope}; Metadata *Ops[] = {File, Scope};
DEFINE_GETIMPL_STORE(MDLexicalBlockFile, (Discriminator), Ops); 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) MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
: Scope(Scope), File(File), Line(Line), Column(Column) {} : Scope(Scope), File(File), Line(Line), Column(Column) {}
MDNodeKeyImpl(const MDLexicalBlock *N) 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()) {} Column(N->getColumn()) {}
bool isKeyOf(const MDLexicalBlock *RHS) const { 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(); Line == RHS->getLine() && Column == RHS->getColumn();
} }
unsigned getHashValue() const { unsigned getHashValue() const {
@ -614,11 +614,11 @@ template <> struct MDNodeKeyImpl<MDLexicalBlockFile> {
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator) MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
: Scope(Scope), File(File), Discriminator(Discriminator) {} : Scope(Scope), File(File), Discriminator(Discriminator) {}
MDNodeKeyImpl(const MDLexicalBlockFile *N) MDNodeKeyImpl(const MDLexicalBlockFile *N)
: Scope(N->getScope()), File(N->getFile()), : Scope(N->getRawScope()), File(N->getRawFile()),
Discriminator(N->getDiscriminator()) {} Discriminator(N->getDiscriminator()) {}
bool isKeyOf(const MDLexicalBlockFile *RHS) const { bool isKeyOf(const MDLexicalBlockFile *RHS) const {
return Scope == RHS->getScope() && File == RHS->getFile() && return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
Discriminator == RHS->getDiscriminator(); Discriminator == RHS->getDiscriminator();
} }
unsigned getHashValue() const { unsigned getHashValue() const {

View File

@ -302,6 +302,7 @@ private:
void visitMDScope(const MDScope &N); void visitMDScope(const MDScope &N);
void visitMDDerivedTypeBase(const MDDerivedTypeBase &N); void visitMDDerivedTypeBase(const MDDerivedTypeBase &N);
void visitMDVariable(const MDVariable &N); void visitMDVariable(const MDVariable &N);
void visitMDLexicalBlockBase(const MDLexicalBlockBase &N);
// InstVisitor overrides... // InstVisitor overrides...
using InstVisitor<Verifier>::visit; 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.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) { 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) { 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} !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9}
!0 = distinct !{} !0 = distinct !{}
!1 = distinct !{} !1 = !MDSubprogram(name: "foo", scope: !2)
!2 = !MDFile(filename: "path/to/file", directory: "/path/to/dir") !2 = !MDFile(filename: "path/to/file", directory: "/path/to/dir")
; CHECK: !3 = !MDLexicalBlock(scope: !0, file: !2, line: 7, column: 35) ; CHECK: !3 = !MDLexicalBlock(scope: !1, file: !2, line: 7, column: 35)
!3 = !MDLexicalBlock(scope: !0, file: !2, line: 7, column: 35) !3 = !MDLexicalBlock(scope: !1, file: !2, line: 7, column: 35)
; CHECK: !4 = !MDLexicalBlock(scope: !0) ; CHECK: !4 = !MDLexicalBlock(scope: !1)
!4 = !MDLexicalBlock(scope: !0) !4 = !MDLexicalBlock(scope: !1)
!5 = !MDLexicalBlock(scope: !0, file: null, line: 0, column: 0) !5 = !MDLexicalBlock(scope: !1, file: null, line: 0, column: 0)
; CHECK: !5 = !MDLexicalBlockFile(scope: !3, file: !2, discriminator: 0) ; CHECK: !5 = !MDLexicalBlockFile(scope: !3, file: !2, discriminator: 0)
; CHECK: !6 = !MDLexicalBlockFile(scope: !3, file: !2, discriminator: 1) ; 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); false, true, 1, 0, true, F);
EXPECT_TRUE(SP.Verify()); EXPECT_TRUE(SP.Verify());
AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty()); 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)); I->setDebugLoc(DebugLoc::get(2, 0, BadScope));
EXPECT_FALSE(SP.Verify()); EXPECT_FALSE(SP.Verify());
DIB.finalize(); DIB.finalize();

View File

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