diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-03-30 16:19:15 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-03-30 16:19:15 +0000 |
commit | 869db50ffd931af466d85ca751a4843fc8aa15bf (patch) | |
tree | 82aa6ac5f6ef61c4b1ddb36c2b8871d7e505e5a6 /llvm/lib | |
parent | d1fdbe7c3266c1a2876dd4a628c881ddf62e0149 (diff) | |
download | bcm5719-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.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 29 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 58 |
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) { |