mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-28 16:28:58 +00:00
Add an IR Verifier check for orphaned DICompileUnits.
A DICompileUnit that is not listed in llvm.dbg.cu will cause assertion failures and/or crashes in the backend. The Verifier should reject this. rdar://problem/25369499 llvm-svn: 264657
This commit is contained in:
parent
c0df326784
commit
ca27a73d17
@ -196,6 +196,9 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
|
||||
/// \brief Keep track of the metadata nodes that have been checked already.
|
||||
SmallPtrSet<const Metadata *, 32> MDNodes;
|
||||
|
||||
/// Track all DICompileUnits visited.
|
||||
SmallPtrSet<const Metadata *, 2> CUVisited;
|
||||
|
||||
/// \brief Track unresolved string-based type references.
|
||||
SmallDenseMap<const MDString *, const MDNode *, 32> UnresolvedTypeRefs;
|
||||
|
||||
@ -302,7 +305,9 @@ public:
|
||||
visitModuleFlags(M);
|
||||
visitModuleIdents(M);
|
||||
|
||||
// Verify type referneces last.
|
||||
verifyCompileUnits();
|
||||
|
||||
// Verify type references last.
|
||||
verifyTypeRefs();
|
||||
|
||||
return !Broken;
|
||||
@ -444,12 +449,15 @@ private:
|
||||
void verifyFrameRecoverIndices();
|
||||
void verifySiblingFuncletUnwinds();
|
||||
|
||||
// Module-level debug info verification...
|
||||
/// @{
|
||||
/// Module-level debug info verification...
|
||||
void verifyTypeRefs();
|
||||
void verifyCompileUnits();
|
||||
template <class MapTy>
|
||||
void verifyBitPieceExpression(const DbgInfoIntrinsic &I,
|
||||
const MapTy &TypeRefs);
|
||||
void visitUnresolvedTypeRef(const MDString *S, const MDNode *N);
|
||||
/// @}
|
||||
};
|
||||
} // End anonymous namespace
|
||||
|
||||
@ -969,6 +977,7 @@ void Verifier::visitDICompileUnit(const DICompileUnit &N) {
|
||||
Assert(Op && isa<DIMacroNode>(Op), "invalid macro ref", &N, Op);
|
||||
}
|
||||
}
|
||||
CUVisited.insert(&N);
|
||||
}
|
||||
|
||||
void Verifier::visitDISubprogram(const DISubprogram &N) {
|
||||
@ -4251,6 +4260,18 @@ void Verifier::visitUnresolvedTypeRef(const MDString *S, const MDNode *N) {
|
||||
Assert(false, "unresolved type ref", S, N);
|
||||
}
|
||||
|
||||
void Verifier::verifyCompileUnits() {
|
||||
auto *CUs = M->getNamedMetadata("llvm.dbg.cu");
|
||||
SmallPtrSet<const Metadata *, 2> Listed;
|
||||
if (CUs)
|
||||
Listed.insert(CUs->op_begin(), CUs->op_end());
|
||||
Assert(
|
||||
std::all_of(CUVisited.begin(), CUVisited.end(),
|
||||
[&Listed](const Metadata *CU) { return Listed.count(CU); }),
|
||||
"All DICompileUnits must be listed in llvm.dbg.cu");
|
||||
CUVisited.clear();
|
||||
}
|
||||
|
||||
void Verifier::verifyTypeRefs() {
|
||||
auto *CUs = M->getNamedMetadata("llvm.dbg.cu");
|
||||
if (!CUs)
|
||||
|
@ -1,8 +1,11 @@
|
||||
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
|
||||
; RUN: verify-uselistorder %s
|
||||
|
||||
; Force a specific numbering.
|
||||
; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9}
|
||||
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9}
|
||||
; CHECK: !llvm.dbg.cu = !{!8, !9}
|
||||
!llvm.dbg.cu = !{!8, !9}
|
||||
|
||||
!0 = distinct !{}
|
||||
!1 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
|
||||
@ -24,3 +27,5 @@
|
||||
!9 = distinct !DICompileUnit(language: 12, file: !1, producer: "",
|
||||
isOptimized: false, flags: "", runtimeVersion: 0,
|
||||
splitDebugFilename: "", emissionKind: 0)
|
||||
!llvm.module.flags = !{!10}
|
||||
!10 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
|
@ -28,11 +28,11 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
|
||||
declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone
|
||||
|
||||
!llvm.module.flags = !{!19}
|
||||
!llvm.dbg.sp = !{!0}
|
||||
!llvm.dbg.cu = !{!2}
|
||||
|
||||
!0 = distinct !DISubprogram(name: "foo", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, file: !18, scope: !1, type: !3)
|
||||
!1 = !DIFile(filename: "li.c", directory: "/private/tmp")
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 2.9 (trunk 127165:127174)", isOptimized: true, emissionKind: 0, file: !18, enums: !9, retainedTypes: !9)
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 2.9 (trunk 127165:127174)", isOptimized: true, emissionKind: 0, file: !18, enums: !9, subprograms: !{!0}, retainedTypes: !9)
|
||||
!3 = !DISubroutineType(types: !4)
|
||||
!4 = !{null}
|
||||
!5 = !DILocalVariable(name: "a", line: 2, arg: 1, scope: !0, file: !1, type: !6)
|
||||
|
10
test/Verifier/dbg-orphaned-compileunit.ll
Normal file
10
test/Verifier/dbg-orphaned-compileunit.ll
Normal file
@ -0,0 +1,10 @@
|
||||
; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s
|
||||
; CHECK: assembly parsed, but does not verify
|
||||
; CHECK-NEXT: All DICompileUnits must be listed in llvm.dbg.cu
|
||||
|
||||
!named = !{!1}
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!llvm.dbg.cu = !{}
|
||||
!1 = distinct !DICompileUnit(file: !2, language: DW_LANG_Fortran77)
|
||||
!2 = !DIFile(filename: "test.f", directory: "")
|
@ -552,7 +552,9 @@ bool ReduceCrashingNamedMD::TestNamedMDs(std::vector<std::string> &NamedMDs) {
|
||||
std::vector<NamedMDNode *> ToDelete;
|
||||
ToDelete.reserve(M->named_metadata_size() - Names.size());
|
||||
for (auto &NamedMD : M->named_metadata())
|
||||
if (!Names.count(NamedMD.getName()))
|
||||
// Always keep a nonempty llvm.dbg.cu because the Verifier would complain.
|
||||
if (!Names.count(NamedMD.getName()) &&
|
||||
(!(NamedMD.getName() == "llvm.dbg.cu" && NamedMD.getNumOperands() > 0)))
|
||||
ToDelete.push_back(&NamedMD);
|
||||
|
||||
for (auto *NamedMD : ToDelete)
|
||||
|
Loading…
x
Reference in New Issue
Block a user