forked from OSchip/llvm-project
[DWARFv5] Verify all-or-nothing constraint on DIFile source
Update IR verifier to check the constraint that DIFile source is present on all files or no files. Differential Revision: https://reviews.llvm.org/D54953 llvm-svn: 348022
This commit is contained in:
parent
d1c9751657
commit
4ed5195712
|
@ -281,6 +281,9 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
|
|||
/// Whether the current function has a DISubprogram attached to it.
|
||||
bool HasDebugInfo = false;
|
||||
|
||||
/// Whether source was present on the first DIFile encountered in each CU.
|
||||
DenseMap<const DICompileUnit *, bool> HasSourceDebugInfo;
|
||||
|
||||
/// Stores the count of how many objects were passed to llvm.localescape for a
|
||||
/// given function and the largest index passed to llvm.localrecover.
|
||||
DenseMap<Function *, std::pair<unsigned, unsigned>> FrameEscapeInfo;
|
||||
|
@ -519,6 +522,9 @@ private:
|
|||
/// Module-level verification that all @llvm.experimental.deoptimize
|
||||
/// declarations share the same calling convention.
|
||||
void verifyDeoptimizeCallingConvs();
|
||||
|
||||
/// Verify all-or-nothing property of DIFile source attribute within a CU.
|
||||
void verifySourceDebugInfo(const DICompileUnit &U, const DIFile &F);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
@ -1032,6 +1038,8 @@ void Verifier::visitDICompileUnit(const DICompileUnit &N) {
|
|||
AssertDI(!N.getFile()->getFilename().empty(), "invalid filename", &N,
|
||||
N.getFile());
|
||||
|
||||
verifySourceDebugInfo(N, *N.getFile());
|
||||
|
||||
AssertDI((N.getEmissionKind() <= DICompileUnit::LastEmissionKind),
|
||||
"invalid emission kind", &N);
|
||||
|
||||
|
@ -1109,6 +1117,8 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
|
|||
AssertDI(N.isDistinct(), "subprogram definitions must be distinct", &N);
|
||||
AssertDI(Unit, "subprogram definitions must have a compile unit", &N);
|
||||
AssertDI(isa<DICompileUnit>(Unit), "invalid unit type", &N, Unit);
|
||||
if (N.getFile())
|
||||
verifySourceDebugInfo(*N.getUnit(), *N.getFile());
|
||||
} else {
|
||||
// Subprogram declarations (part of the type hierarchy).
|
||||
AssertDI(!Unit, "subprogram declarations must not have a compile unit", &N);
|
||||
|
@ -4744,6 +4754,14 @@ void Verifier::verifyDeoptimizeCallingConvs() {
|
|||
}
|
||||
}
|
||||
|
||||
void Verifier::verifySourceDebugInfo(const DICompileUnit &U, const DIFile &F) {
|
||||
bool HasSource = F.getSource().hasValue();
|
||||
if (!HasSourceDebugInfo.count(&U))
|
||||
HasSourceDebugInfo[&U] = HasSource;
|
||||
AssertDI(HasSource == HasSourceDebugInfo[&U],
|
||||
"inconsistent use of embedded source");
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Implement the public interfaces to this file...
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
; RUN: llvm-as < %s 2>&1 >/dev/null | FileCheck %s
|
||||
|
||||
; Ensure we reject debug info where the DIFiles of a DICompileUnit mix source
|
||||
; and no-source.
|
||||
|
||||
define dso_local void @foo() !dbg !5 {
|
||||
ret void
|
||||
}
|
||||
|
||||
define dso_local void @bar() !dbg !6 {
|
||||
ret void
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!4}
|
||||
!llvm.module.flags = !{!0, !1}
|
||||
|
||||
!0 = !{i32 2, !"Dwarf Version", i32 5}
|
||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
|
||||
!2 = !DIFile(filename: "foo.c", directory: "dir", source: "void foo() { }\0A")
|
||||
; CHECK: inconsistent use of embedded source
|
||||
; CHECK: warning: ignoring invalid debug info
|
||||
!3 = !DIFile(filename: "bar.h", directory: "dir")
|
||||
|
||||
!4 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2)
|
||||
!5 = distinct !DISubprogram(name: "foo", file: !2, unit: !4)
|
||||
!6 = distinct !DISubprogram(name: "bar", file: !3, unit: !4)
|
|
@ -0,0 +1,41 @@
|
|||
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
|
||||
; RUN: verify-uselistorder %s
|
||||
|
||||
; Ensure we accept debug info where DIFiles within a DICompileUnit either all
|
||||
; have source, or none have source.
|
||||
|
||||
define dso_local void @foo() !dbg !6 {
|
||||
ret void
|
||||
}
|
||||
|
||||
define dso_local void @bar() !dbg !7 {
|
||||
ret void
|
||||
}
|
||||
|
||||
define dso_local void @baz() !dbg !9 {
|
||||
ret void
|
||||
}
|
||||
|
||||
define dso_local void @qux() !dbg !11 {
|
||||
ret void
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!0, !2}
|
||||
!llvm.module.flags = !{!4, !5}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1)
|
||||
; CHECK: !1 = !DIFile(filename: "foo.c", directory: "dir", source: "void foo() { }\0A")
|
||||
!1 = !DIFile(filename: "foo.c", directory: "dir", source: "void foo() { }\0A")
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3)
|
||||
; CHECK: !3 = !DIFile(filename: "qux.h", directory: "dir")
|
||||
!3 = !DIFile(filename: "qux.h", directory: "dir")
|
||||
!4 = !{i32 2, !"Dwarf Version", i32 5}
|
||||
!5 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!6 = distinct !DISubprogram(name: "foo", file: !1, unit: !0)
|
||||
!7 = distinct !DISubprogram(name: "bar", file: !8, unit: !0)
|
||||
; CHECK: !8 = !DIFile(filename: "bar.h", directory: "dir", source: "void bar() { }\0A")
|
||||
!8 = !DIFile(filename: "bar.h", directory: "dir", source: "void bar() { }\0A")
|
||||
!9 = distinct !DISubprogram(name: "baz", file: !10, unit: !2)
|
||||
; CHECK: !10 = !DIFile(filename: "baz.c", directory: "dir")
|
||||
!10 = !DIFile(filename: "baz.c", directory: "dir")
|
||||
!11 = distinct !DISubprogram(name: "qux", file: !3, unit: !2)
|
Loading…
Reference in New Issue