Skip to content

Commit 2ee4d03

Browse files
committed
[Verifier] definition subprograms cannot be nested within DICompositeType when enabling ODR.
Resolve #61932. We should add the validation. LLVM can't handle IR where subprogram definitions are nested within DICompositeType when doing LTO builds, because there's no good way to cross the CU boundary to insert a nested DISubprogram definition in one CU into a type defined in another CU. The test cases `cross-cu-inlining-2.ll` and `cross-cu-inlining-ranges.ll` can be deleted. In the `cross-cu-inlining-2.ll`, the low pc and high pc of the CU are also incorrect. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D152095
1 parent b986343 commit 2ee4d03

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

llvm/lib/IR/Verifier.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,15 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
14291429
CheckDI(N.isDistinct(), "subprogram definitions must be distinct", &N);
14301430
CheckDI(Unit, "subprogram definitions must have a compile unit", &N);
14311431
CheckDI(isa<DICompileUnit>(Unit), "invalid unit type", &N, Unit);
1432+
// There's no good way to cross the CU boundary to insert a nested
1433+
// DISubprogram definition in one CU into a type defined in another CU.
1434+
auto *CT = dyn_cast_or_null<DICompositeType>(N.getRawScope());
1435+
if (CT && CT->getRawIdentifier() &&
1436+
M.getContext().isODRUniquingDebugTypes())
1437+
CheckDI(N.getDeclaration(),
1438+
"definition subprograms cannot be nested within DICompositeType "
1439+
"when enabling ODR",
1440+
&N);
14321441
if (N.getFile())
14331442
verifySourceDebugInfo(*N.getUnit(), *N.getFile());
14341443
} else {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; RUN: opt -passes=verify -S < %s 2>&1 | FileCheck %s
2+
; RUN: opt -passes=verify -S --disable-debug-info-type-map < %s | FileCheck --check-prefix=CHECK-NOT-ODR %s
3+
4+
; Same content as the disubprogram-declaration-within-struct.ll file, except the `identifier` for `DICompositeType` is removed.
5+
6+
; ModuleID = 'foo.7e668e4a-cgu.0'
7+
source_filename = "foo.7e668e4a-cgu.0"
8+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
9+
target triple = "x86_64-unknown-linux-gnu"
10+
11+
; foo::Foo::bar
12+
; Function Attrs: nonlazybind uwtable
13+
define void @_ZN3foo3Foo3bar17h32d65c44145019c8E() unnamed_addr #0 !dbg !6 {
14+
start:
15+
ret void, !dbg !14
16+
}
17+
18+
attributes #0 = { nonlazybind uwtable "probe-stack"="__rust_probestack" "target-cpu"="x86-64" }
19+
20+
!llvm.module.flags = !{!0, !1, !2, !3}
21+
!llvm.dbg.cu = !{!4}
22+
23+
!0 = !{i32 7, !"PIC Level", i32 2}
24+
!1 = !{i32 2, !"RtLibUseGOT", i32 1}
25+
!2 = !{i32 2, !"Dwarf Version", i32 4}
26+
!3 = !{i32 2, !"Debug Info Version", i32 3}
27+
!4 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !5, producer: "clang LLVM (rustc version 1.69.0 (84c898d65 2023-04-16))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false)
28+
!5 = !DIFile(filename: "foo.rs/@/foo.7e668e4a-cgu.0", directory: "/tmp")
29+
!6 = distinct !DISubprogram(name: "bar", linkageName: "_ZN3foo3Foo3bar17h32d65c44145019c8E", scope: !8, file: !7, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !4, templateParams: !11, retainedNodes: !11)
30+
!7 = !DIFile(filename: "foo.rs", directory: "/tmp", checksumkind: CSK_MD5, checksum: "427d9b572596c2f310b6185a1781f222")
31+
!8 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", scope: !10, file: !9, align: 8, elements: !11)
32+
!9 = !DIFile(filename: "<unknown>", directory: "")
33+
!10 = !DINamespace(name: "foo", scope: null)
34+
!11 = !{}
35+
!12 = !DISubroutineType(types: !13)
36+
!13 = !{null}
37+
!14 = !DILocation(line: 6, column: 6, scope: !6)
38+
39+
; CHECK-NOT: definition subprograms cannot be nested within DICompositeType when enabling ODR
40+
; CHECK-NOT: warning: ignoring invalid debug info
41+
42+
; CHECK-NOT-ODR-NOT: definition subprograms cannot be nested within DICompositeType when enabling ODR
43+
; CHECK-NOT-ODR-NOT: warning: ignoring invalid debug info
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
; RUN: opt -passes=verify -disable-output < %s 2>&1 | FileCheck %s
2+
; RUN: opt -passes=verify -S --disable-debug-info-type-map < %s | FileCheck --check-prefix=CHECK-NOT-ODR %s
3+
4+
; The Rust source:
5+
; pub struct Foo;
6+
; impl Foo {
7+
; pub fn bar() {}
8+
; }
9+
10+
; ModuleID = 'foo.7e668e4a-cgu.0'
11+
source_filename = "foo.7e668e4a-cgu.0"
12+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
13+
target triple = "x86_64-unknown-linux-gnu"
14+
15+
; foo::Foo::bar
16+
; Function Attrs: nonlazybind uwtable
17+
define void @_ZN3foo3Foo3bar17h32d65c44145019c8E() unnamed_addr #0 !dbg !6 {
18+
start:
19+
ret void, !dbg !14
20+
}
21+
22+
attributes #0 = { nonlazybind uwtable "probe-stack"="__rust_probestack" "target-cpu"="x86-64" }
23+
24+
!llvm.module.flags = !{!0, !1, !2, !3}
25+
!llvm.dbg.cu = !{!4}
26+
27+
!0 = !{i32 7, !"PIC Level", i32 2}
28+
!1 = !{i32 2, !"RtLibUseGOT", i32 1}
29+
!2 = !{i32 2, !"Dwarf Version", i32 4}
30+
!3 = !{i32 2, !"Debug Info Version", i32 3}
31+
!4 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !5, producer: "clang LLVM (rustc version 1.69.0 (84c898d65 2023-04-16))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false)
32+
!5 = !DIFile(filename: "foo.rs/@/foo.7e668e4a-cgu.0", directory: "/tmp")
33+
!6 = distinct !DISubprogram(name: "bar", linkageName: "_ZN3foo3Foo3bar17h32d65c44145019c8E", scope: !8, file: !7, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !4, templateParams: !11, retainedNodes: !11)
34+
!7 = !DIFile(filename: "foo.rs", directory: "/tmp", checksumkind: CSK_MD5, checksum: "427d9b572596c2f310b6185a1781f222")
35+
!8 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", scope: !10, file: !9, align: 8, elements: !11, identifier: "a8fd67db4e906c9c4aceea39cb8b0f61")
36+
!9 = !DIFile(filename: "<unknown>", directory: "")
37+
!10 = !DINamespace(name: "foo", scope: null)
38+
!11 = !{}
39+
!12 = !DISubroutineType(types: !13)
40+
!13 = !{null}
41+
!14 = !DILocation(line: 6, column: 6, scope: !6)
42+
43+
; CHECK: definition subprograms cannot be nested within DICompositeType when enabling ODR
44+
; CHECK: warning: ignoring invalid debug info
45+
46+
; CHECK-NOT-ODR-NOT: definition subprograms cannot be nested within DICompositeType when enabling ODR
47+
; CHECK-NOT-ODR-NOT: warning: ignoring invalid debug info

0 commit comments

Comments
 (0)