Skip to content

Commit 58b8e6e

Browse files
authored
[DebugInfo][IR] Verifier checks for the extraData (#167971)
LLVM IR verifier checks for `extraData` in debug info metadata. This is a follow-up PR based on discussions in #165023
1 parent ac6e48d commit 58b8e6e

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

llvm/lib/IR/Verifier.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,7 @@ void Verifier::visitMetadataAsValue(const MetadataAsValue &MDV, Function *F) {
11581158
static bool isType(const Metadata *MD) { return !MD || isa<DIType>(MD); }
11591159
static bool isScope(const Metadata *MD) { return !MD || isa<DIScope>(MD); }
11601160
static bool isDINode(const Metadata *MD) { return !MD || isa<DINode>(MD); }
1161+
static bool isMDTuple(const Metadata *MD) { return !MD || isa<MDTuple>(MD); }
11611162

11621163
void Verifier::visitDILocation(const DILocation &N) {
11631164
CheckDI(N.getRawScope() && isa<DILocalScope>(N.getRawScope()),
@@ -1320,6 +1321,30 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) {
13201321
if (N.getTag() == dwarf::DW_TAG_ptr_to_member_type) {
13211322
CheckDI(isType(N.getRawExtraData()), "invalid pointer to member type", &N,
13221323
N.getRawExtraData());
1324+
} else if (N.getTag() == dwarf::DW_TAG_template_alias) {
1325+
CheckDI(isMDTuple(N.getRawExtraData()), "invalid template parameters", &N,
1326+
N.getRawExtraData());
1327+
} else if (N.getTag() == dwarf::DW_TAG_inheritance ||
1328+
N.getTag() == dwarf::DW_TAG_member ||
1329+
N.getTag() == dwarf::DW_TAG_variable) {
1330+
auto *ExtraData = N.getRawExtraData();
1331+
auto IsValidExtraData = [&]() {
1332+
if (ExtraData == nullptr)
1333+
return true;
1334+
if (isa<ConstantAsMetadata>(ExtraData) || isa<MDString>(ExtraData) ||
1335+
isa<DIObjCProperty>(ExtraData))
1336+
return true;
1337+
if (auto *Tuple = dyn_cast<MDTuple>(ExtraData)) {
1338+
if (Tuple->getNumOperands() != 1)
1339+
return false;
1340+
return isa_and_nonnull<ConstantAsMetadata>(Tuple->getOperand(0).get());
1341+
}
1342+
return false;
1343+
};
1344+
CheckDI(IsValidExtraData(),
1345+
"extraData must be ConstantAsMetadata, MDString, DIObjCProperty, "
1346+
"or MDTuple with single ConstantAsMetadata operand",
1347+
&N, ExtraData);
13231348
}
13241349

13251350
if (N.getTag() == dwarf::DW_TAG_set_type) {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
; RUN: not opt -S < %s 2>&1 | FileCheck %s
2+
3+
;; Test that extraData with MDTuple is only allowed for specific DWARF tags:
4+
;; DW_TAG_inheritance, DW_TAG_member, and DW_TAG_variable
5+
6+
!llvm.module.flags = !{!0}
7+
!0 = !{i32 2, !"Debug Info Version", i32 3}
8+
9+
!1 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
10+
11+
; Keep all metadata nodes alive so verifier can check them
12+
!named = !{!1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16}
13+
!2 = !{i32 0}
14+
15+
; Valid: DW_TAG_inheritance with tuple extraData should be accepted
16+
!3 = !DIDerivedType(tag: DW_TAG_inheritance, baseType: !1, size: 32, extraData: !2)
17+
18+
; Valid: DW_TAG_member with tuple extraData should be accepted
19+
!4 = !DIDerivedType(tag: DW_TAG_member, name: "field", baseType: !1, size: 32, extraData: !2)
20+
21+
; Valid: DW_TAG_variable (static member) with tuple extraData should be accepted
22+
!5 = !DIDerivedType(tag: DW_TAG_variable, name: "var", baseType: !1, extraData: !2, flags: DIFlagStaticMember)
23+
24+
; Invalid: Empty tuple should be rejected
25+
!6 = !{}
26+
; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
27+
; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_member
28+
!7 = !DIDerivedType(tag: DW_TAG_member, name: "field2", baseType: !1, extraData: !6)
29+
30+
; Invalid: Tuple with multiple operands should be rejected
31+
!8 = !{i32 0, i32 1}
32+
; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
33+
; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_member
34+
!9 = !DIDerivedType(tag: DW_TAG_member, name: "field3", baseType: !1, extraData: !8)
35+
36+
; Invalid: Tuple with non-ConstantAsMetadata operand should be rejected
37+
!10 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
38+
!11 = !{!10}
39+
; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
40+
; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_member
41+
!12 = !DIDerivedType(tag: DW_TAG_member, name: "field4", baseType: !1, extraData: !11)
42+
43+
; Valid: DW_TAG_template_alias with proper template parameters tuple
44+
; Template aliases are handled specially and accept any MDTuple for template parameters
45+
!13 = !DITemplateTypeParameter(name: "T", type: !1)
46+
!14 = !{!13}
47+
!15 = !DIDerivedType(tag: DW_TAG_template_alias, name: "MyAlias", baseType: !1, extraData: !14)
48+
49+
; Invalid: DW_TAG_template_alias with non-tuple extraData should fail
50+
; CHECK: invalid template parameters
51+
; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_template_alias
52+
!16 = !DIDerivedType(tag: DW_TAG_template_alias, name: "FailingAlias", baseType: !1, extraData: i32 42)
53+
54+
; CHECK: warning: ignoring invalid debug info
55+

0 commit comments

Comments
 (0)