Description
When compiling following source, clang creates a virtual destructor for A
with an artificial vtt
argument. The DILocalVariable
for vtt
correctly has arg: 2
.
However, the field types
of the DISubroutineType
for this virtual destructor seems to miss the additional parameter, as it only has two members and thus represents a function with only one parameter.
Source:
struct B {
virtual ~B() {}
};
struct A : virtual B {
};
A a;
LLVM-IR:
[...]
!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !3, line: 5, size: 64, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !6, vtableHolder: !8, identifier: "_ZTS1A")
[...]
!34 = !DISubroutineType(types: !35)
!35 = !{null, !36}
!36 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
[...]
!70 = distinct !DISubprogram(name: "~A", linkageName: "_ZN1AD2Ev", scope: !5, file: !3, line: 5, type: !34, scopeLine: 5, flags: DIFlagArtificial | DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, declaration: !44, retainedNodes: !38)
!71 = !DILocalVariable(name: "this", arg: 1, scope: !70, type: !40, flags: DIFlagArtificial | DIFlagObjectPointer)
!72 = !DILocation(line: 0, scope: !70)
!73 = !DILocalVariable(name: "vtt", arg: 2, scope: !70, type: !74, flags: DIFlagArtificial)
!74 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !75, size: 64)
!75 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
[...]
I generated the IR using clang 19.1.0-rc2 on x86_64-unknown-linux-gnu
.
DWARF generated from this IR is not affected and includes all formal parameters.
The issue seems to be that in ItaniumCXXABI::addImplicitStructorParams
, the parameter is added, but in CGDebugInfo::getOrCreateMethodType
another type array is read to create the DISubroutineType
.
llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp
Lines 1870 to 1890 in d033ae1
llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp
Lines 1938 to 1946 in d033ae1