Skip to content

Commit a892595

Browse files
committed
[Coroutines] Fix debug info scoping for nested structs in coroutine frames
1 parent 64c3ba8 commit a892595

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

llvm/lib/Transforms/Coroutines/CoroFrame.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -639,10 +639,10 @@ static DIType *solveDIType(DIBuilder &Builder, Type *Ty,
639639
SmallVector<Metadata *, 16> Elements;
640640
for (unsigned I = 0; I < StructTy->getNumElements(); I++) {
641641
DIType *DITy = solveDIType(Builder, StructTy->getElementType(I), Layout,
642-
Scope, LineNum, DITypeCache);
642+
DIStruct, LineNum, DITypeCache);
643643
assert(DITy);
644644
Elements.push_back(Builder.createMemberType(
645-
Scope, DITy->getName(), Scope->getFile(), LineNum,
645+
DIStruct, DITy->getName(), DIStruct->getFile(), LineNum,
646646
DITy->getSizeInBits(), DITy->getAlignInBits(),
647647
Layout.getStructLayout(StructTy)->getElementOffsetInBits(I),
648648
llvm::DINode::FlagArtificial, DITy));
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
; RUN: opt < %s -passes='cgscc(coro-split)' -S | FileCheck %s
2+
3+
; Test that nested structs in coroutine frames have correct debug info scoping.
4+
5+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
6+
target triple = "x86_64-unknown-linux-gnu"
7+
8+
; Minimal nested struct types that trigger the scoping issue
9+
%"struct.Inner" = type { i32, ptr }
10+
%"struct.Outer" = type { %"struct.Inner", i64 }
11+
%"class.Promise" = type { %"struct.Outer" }
12+
13+
define void @test_coro_function() presplitcoroutine !dbg !10 {
14+
entry:
15+
%__promise = alloca %"class.Promise", align 8
16+
%0 = call token @llvm.coro.id(i32 0, ptr %__promise, ptr null, ptr null)
17+
%1 = call ptr @llvm.coro.begin(token %0, ptr null)
18+
%2 = call token @llvm.coro.save(ptr null)
19+
ret void
20+
}
21+
22+
; The test passes if the debug info is generated without crashing
23+
; CHECK: define void @test_coro_function()
24+
25+
; Check that frame debug info is generated
26+
; CHECK: ![[FRAME_TYPE:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{{.*}}.coro_frame_ty"
27+
28+
; Key validation: Check that nested structs have the correct scope hierarchy
29+
; 1. Promise should be scoped to the frame
30+
; CHECK: ![[PROMISE:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "class_Promise", scope: ![[FRAME_TYPE]]
31+
32+
; 2. Outer should be scoped to Promise (not the frame!)
33+
; CHECK: ![[OUTER:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "struct_Outer", scope: ![[PROMISE]]
34+
35+
; 3. Inner should be scoped to Outer (proper nesting)
36+
; CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "struct_Inner", scope: ![[OUTER]]
37+
38+
declare token @llvm.coro.id(i32, ptr readnone, ptr readonly, ptr)
39+
declare ptr @llvm.coro.begin(token, ptr writeonly)
40+
declare token @llvm.coro.save(ptr)
41+
42+
!llvm.dbg.cu = !{!0}
43+
!llvm.module.flags = !{!9}
44+
45+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
46+
!1 = !DIFile(filename: "test.cpp", directory: ".")
47+
!9 = !{i32 2, !"Debug Info Version", i32 3}
48+
!10 = distinct !DISubprogram(name: "test_coro_function", scope: !1, file: !1, line: 1, type: !11, spFlags: DISPFlagDefinition, unit: !0)
49+
!11 = !DISubroutineType(types: !12)
50+
!12 = !{null}

0 commit comments

Comments
 (0)