summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-03-30 16:19:15 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-03-30 16:19:15 +0000
commit869db50ffd931af466d85ca751a4843fc8aa15bf (patch)
tree82aa6ac5f6ef61c4b1ddb36c2b8871d7e505e5a6 /llvm/lib
parentd1fdbe7c3266c1a2876dd4a628c881ddf62e0149 (diff)
downloadbcm5719-llvm-869db50ffd931af466d85ca751a4843fc8aa15bf.tar.gz
bcm5719-llvm-869db50ffd931af466d85ca751a4843fc8aa15bf.zip
Verifier: Check operands of MDSubprogram nodes
Check operands of `MDSubprogram`s in the verifier, and update the accessors and factory functions to use more specific types. There were a lot of broken testcases, which I fixed in r233466. If you have out-of-tree tests for debug info, you probably need similar changes to the ones I made there. llvm-svn: 233559
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp16
-rw-r--r--llvm/lib/IR/DIBuilder.cpp22
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h29
-rw-r--r--llvm/lib/IR/Verifier.cpp58
4 files changed, 94 insertions, 31 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index a3dde894070..c5782f5937f 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1629,23 +1629,23 @@ static void writeMDSubprogram(raw_ostream &Out, const MDSubprogram *N,
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printString("name", N->getName());
Printer.printString("linkageName", N->getLinkageName());
- 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.printMetadata("type", N->getType());
+ Printer.printMetadata("type", N->getRawType());
Printer.printBool("isLocal", N->isLocalToUnit());
Printer.printBool("isDefinition", N->isDefinition());
Printer.printInt("scopeLine", N->getScopeLine());
- Printer.printMetadata("containingType", N->getContainingType());
+ Printer.printMetadata("containingType", N->getRawContainingType());
Printer.printDwarfEnum("virtuality", N->getVirtuality(),
dwarf::VirtualityString);
Printer.printInt("virtualIndex", N->getVirtualIndex());
Printer.printDIFlags("flags", N->getFlags());
Printer.printBool("isOptimized", N->isOptimized());
- Printer.printMetadata("function", N->getFunction());
- Printer.printMetadata("templateParams", N->getTemplateParams());
- Printer.printMetadata("declaration", N->getDeclaration());
- Printer.printMetadata("variables", N->getVariables());
+ Printer.printMetadata("function", N->getRawFunction());
+ Printer.printMetadata("templateParams", N->getRawTemplateParams());
+ Printer.printMetadata("declaration", N->getRawDeclaration());
+ Printer.printMetadata("variables", N->getRawVariables());
Out << ")";
}
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index dfbc1315218..28d27d201c0 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -674,9 +674,11 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name,
"function types should be subroutines");
auto *Node = MDSubprogram::get(
VMContext, DIScope(getNonCompileUnitScope(Context)).getRef(), Name,
- LinkageName, File.getFileNode(), LineNo, Ty, isLocalToUnit, isDefinition,
- ScopeLine, nullptr, 0, 0, Flags, isOptimized, getConstantOrNull(Fn),
- TParams, Decl, MDNode::getTemporary(VMContext, None).release());
+ LinkageName, File.get(), LineNo, cast_or_null<MDSubroutineType>(Ty.get()),
+ isLocalToUnit, isDefinition, ScopeLine, nullptr, 0, 0, Flags, isOptimized,
+ getConstantOrNull(Fn), cast_or_null<MDTuple>(TParams),
+ cast_or_null<MDSubprogram>(Decl),
+ MDTuple::getTemporary(VMContext, None).release());
if (isDefinition)
AllSubprograms.push_back(Node);
@@ -694,9 +696,11 @@ DIBuilder::createTempFunctionFwdDecl(DIDescriptor Context, StringRef Name,
MDNode *TParams, MDNode *Decl) {
return MDSubprogram::getTemporary(
VMContext, DIScope(getNonCompileUnitScope(Context)).getRef(), Name,
- LinkageName, File.getFileNode(), LineNo, Ty, isLocalToUnit,
+ LinkageName, File.get(), LineNo,
+ cast_or_null<MDSubroutineType>(Ty.get()), isLocalToUnit,
isDefinition, ScopeLine, nullptr, 0, 0, Flags, isOptimized,
- getConstantOrNull(Fn), TParams, Decl, nullptr).release();
+ getConstantOrNull(Fn), cast_or_null<MDTuple>(TParams),
+ cast_or_null<MDSubprogram>(Decl), nullptr).release();
}
DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name,
@@ -714,10 +718,10 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name,
"the compile unit.");
// FIXME: Do we want to use different scope/lines?
auto *Node = MDSubprogram::get(
- VMContext, DIScope(Context).getRef(), Name, LinkageName, F.getFileNode(),
- LineNo, Ty, isLocalToUnit, isDefinition, LineNo, VTableHolder.getRef(),
- VK, VIndex, Flags, isOptimized, getConstantOrNull(Fn), TParam, nullptr,
- nullptr);
+ VMContext, DIScope(Context).getRef(), Name, LinkageName, F.get(), LineNo,
+ cast_or_null<MDSubroutineType>(Ty.get()), isLocalToUnit, isDefinition,
+ LineNo, VTableHolder.getRef(), VK, VIndex, Flags, isOptimized,
+ getConstantOrNull(Fn), cast_or_null<MDTuple>(TParam), nullptr, nullptr);
if (isDefinition)
AllSubprograms.push_back(Node);
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 21999822346..efb741f13fd 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -550,31 +550,32 @@ template <> struct MDNodeKeyImpl<MDSubprogram> {
Function(Function), TemplateParams(TemplateParams),
Declaration(Declaration), Variables(Variables) {}
MDNodeKeyImpl(const MDSubprogram *N)
- : Scope(N->getScope()), Name(N->getName()),
- LinkageName(N->getLinkageName()), File(N->getFile()),
- Line(N->getLine()), Type(N->getType()),
+ : Scope(N->getRawScope()), Name(N->getName()),
+ LinkageName(N->getLinkageName()), File(N->getRawFile()),
+ Line(N->getLine()), Type(N->getRawType()),
IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
- ScopeLine(N->getScopeLine()), ContainingType(N->getContainingType()),
+ ScopeLine(N->getScopeLine()), ContainingType(N->getRawContainingType()),
Virtuality(N->getVirtuality()), VirtualIndex(N->getVirtualIndex()),
Flags(N->getFlags()), IsOptimized(N->isOptimized()),
- Function(N->getFunction()), TemplateParams(N->getTemplateParams()),
- Declaration(N->getDeclaration()), Variables(N->getVariables()) {}
+ Function(N->getRawFunction()),
+ TemplateParams(N->getRawTemplateParams()),
+ Declaration(N->getRawDeclaration()), Variables(N->getRawVariables()) {}
bool isKeyOf(const MDSubprogram *RHS) const {
- return Scope == RHS->getScope() && Name == RHS->getName() &&
- LinkageName == RHS->getLinkageName() && File == RHS->getFile() &&
- Line == RHS->getLine() && Type == RHS->getType() &&
+ return Scope == RHS->getRawScope() && Name == RHS->getName() &&
+ LinkageName == RHS->getLinkageName() && File == RHS->getRawFile() &&
+ Line == RHS->getLine() && Type == RHS->getRawType() &&
IsLocalToUnit == RHS->isLocalToUnit() &&
IsDefinition == RHS->isDefinition() &&
ScopeLine == RHS->getScopeLine() &&
- ContainingType == RHS->getContainingType() &&
+ ContainingType == RHS->getRawContainingType() &&
Virtuality == RHS->getVirtuality() &&
VirtualIndex == RHS->getVirtualIndex() && Flags == RHS->getFlags() &&
IsOptimized == RHS->isOptimized() &&
- Function == RHS->getFunction() &&
- TemplateParams == RHS->getTemplateParams() &&
- Declaration == RHS->getDeclaration() &&
- Variables == RHS->getVariables();
+ Function == RHS->getRawFunction() &&
+ TemplateParams == RHS->getRawTemplateParams() &&
+ Declaration == RHS->getRawDeclaration() &&
+ Variables == RHS->getRawVariables();
}
unsigned getHashValue() const {
return hash_combine(Scope, Name, LinkageName, File, Line, Type,
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index af79984f59a..e4aea237bfc 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -296,6 +296,7 @@ private:
void visitBasicBlock(BasicBlock &BB);
void visitRangeMetadata(Instruction& I, MDNode* Range, Type* Ty);
+ template <class Ty> bool isValidMetadataArray(const MDTuple &N);
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
#include "llvm/IR/Metadata.def"
void visitMDScope(const MDScope &N);
@@ -679,6 +680,30 @@ static bool isScopeRef(const Metadata *MD) {
return isa<MDScope>(MD);
}
+template <class Ty>
+bool isValidMetadataArrayImpl(const MDTuple &N, bool AllowNull) {
+ for (Metadata *MD : N.operands()) {
+ if (MD) {
+ if (!isa<Ty>(MD))
+ return false;
+ } else {
+ if (!AllowNull)
+ return false;
+ }
+ }
+ return true;
+}
+
+template <class Ty>
+bool isValidMetadataArray(const MDTuple &N) {
+ return isValidMetadataArrayImpl<Ty>(N, /* AllowNull */ false);
+}
+
+template <class Ty>
+bool isValidMetadataNullArray(const MDTuple &N) {
+ return isValidMetadataArrayImpl<Ty>(N, /* AllowNull */ true);
+}
+
void Verifier::visitMDLocation(const MDLocation &N) {
Assert(N.getRawScope() && isa<MDLocalScope>(N.getRawScope()),
"location requires a valid scope", &N, N.getRawScope());
@@ -811,6 +836,39 @@ void Verifier::visitMDCompileUnit(const MDCompileUnit &N) {
void Verifier::visitMDSubprogram(const MDSubprogram &N) {
Assert(N.getTag() == dwarf::DW_TAG_subprogram, "invalid tag", &N);
+ Assert(isScopeRef(N.getRawScope()), "invalid scope", &N, N.getRawScope());
+ if (auto *T = N.getRawType())
+ Assert(isa<MDSubroutineType>(T), "invalid subroutine type", &N, T);
+ Assert(isTypeRef(N.getRawContainingType()), "invalid containing type", &N,
+ N.getRawContainingType());
+ if (auto *RawF = N.getRawFunction()) {
+ auto *FMD = dyn_cast<ConstantAsMetadata>(RawF);
+ auto *F = FMD ? FMD->getValue() : nullptr;
+ auto *FT = F ? dyn_cast<PointerType>(F->getType()) : nullptr;
+ Assert(F && (isa<Function>(F) || isa<ConstantPointerNull>(F)) && FT &&
+ isa<FunctionType>(FT->getElementType()),
+ "invalid function", &N, F);
+ }
+ if (N.getRawTemplateParams()) {
+ auto *Params = dyn_cast<MDTuple>(N.getRawTemplateParams());
+ Assert(Params, "invalid template params", &N, Params);
+ for (Metadata *Op : Params->operands()) {
+ Assert(Op && isa<MDTemplateParameter>(Op), "invalid template parameter",
+ &N, Params, Op);
+ }
+ }
+ if (auto *S = N.getRawDeclaration()) {
+ Assert(isa<MDSubprogram>(S) && !cast<MDSubprogram>(S)->isDefinition(),
+ "invalid subprogram declaration", &N, S);
+ }
+ if (N.getRawVariables()) {
+ auto *Vars = dyn_cast<MDTuple>(N.getRawVariables());
+ Assert(Vars, "invalid variable list", &N, Vars);
+ for (Metadata *Op : Vars->operands()) {
+ Assert(Op && isa<MDLocalVariable>(Op), "invalid local variable", &N, Vars,
+ Op);
+ }
+ }
}
void Verifier::visitMDLexicalBlock(const MDLexicalBlock &N) {
OpenPOWER on IntegriCloud