[llvm] [DebugInfo][LLVM IR] Verifier checks for the extraData (PR #167971)
Laxman Sole via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 17 12:00:22 PST 2025
https://github.com/laxmansole updated https://github.com/llvm/llvm-project/pull/167971
>From dbd2f08dacf696b5ea1a9d21da28872883e3c2a9 Mon Sep 17 00:00:00 2001
From: Laxman Sole <lsole at nvidia.com>
Date: Thu, 13 Nov 2025 14:07:37 -0800
Subject: [PATCH 1/3] Verifier checks for the extraData
---
llvm/lib/IR/Verifier.cpp | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index fa18c3cd0f404..b01ca73aa3623 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1320,6 +1320,23 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) {
if (N.getTag() == dwarf::DW_TAG_ptr_to_member_type) {
CheckDI(isType(N.getRawExtraData()), "invalid pointer to member type", &N,
N.getRawExtraData());
+ } else if (N.getTag() == dwarf::DW_TAG_template_alias) {
+ CheckDI(isa<MDTuple>(N.getRawExtraData()), "invalid template parameters",
+ &N, N.getRawExtraData());
+ } else if (auto *ExtraData = N.getRawExtraData()) {
+ auto IsValidExtraData = [&]() {
+ if (isa<ConstantAsMetadata>(ExtraData) || isa<MDString>(ExtraData) ||
+ isa<DIObjCProperty>(ExtraData))
+ return true;
+ if (auto *Tuple = dyn_cast<MDTuple>(ExtraData))
+ return Tuple->getNumOperands() == 1 &&
+ isa<ConstantAsMetadata>(Tuple->getOperand(0));
+ return false;
+ };
+ CheckDI(IsValidExtraData(),
+ "extraData must be ConstantAsMetadata, MDString, DIObjCProperty, "
+ "or MDTuple with single ConstantAsMetadata operand",
+ &N, ExtraData);
}
if (N.getTag() == dwarf::DW_TAG_set_type) {
>From 43ce782044eccbe1a5d465f2767112d49794bd12 Mon Sep 17 00:00:00 2001
From: Laxman Sole <lsole at nvidia.com>
Date: Fri, 14 Nov 2025 19:06:55 -0800
Subject: [PATCH 2/3] Updating verifier checks for to handle null references
and adding lit test
---
llvm/lib/IR/Verifier.cpp | 17 +++--
.../Verifier/diderivedtype-extradata-tuple.ll | 66 +++++++++++++++++++
2 files changed, 78 insertions(+), 5 deletions(-)
create mode 100644 llvm/test/Verifier/diderivedtype-extradata-tuple.ll
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index b01ca73aa3623..c60f9c4808420 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1158,6 +1158,7 @@ void Verifier::visitMetadataAsValue(const MetadataAsValue &MDV, Function *F) {
static bool isType(const Metadata *MD) { return !MD || isa<DIType>(MD); }
static bool isScope(const Metadata *MD) { return !MD || isa<DIScope>(MD); }
static bool isDINode(const Metadata *MD) { return !MD || isa<DINode>(MD); }
+static bool isMDTuple(const Metadata *MD) { return !MD || isa<MDTuple>(MD); }
void Verifier::visitDILocation(const DILocation &N) {
CheckDI(N.getRawScope() && isa<DILocalScope>(N.getRawScope()),
@@ -1321,16 +1322,22 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) {
CheckDI(isType(N.getRawExtraData()), "invalid pointer to member type", &N,
N.getRawExtraData());
} else if (N.getTag() == dwarf::DW_TAG_template_alias) {
- CheckDI(isa<MDTuple>(N.getRawExtraData()), "invalid template parameters",
- &N, N.getRawExtraData());
+ CheckDI(isMDTuple(N.getRawExtraData()), "invalid template parameters", &N,
+ N.getRawExtraData());
} else if (auto *ExtraData = N.getRawExtraData()) {
auto IsValidExtraData = [&]() {
if (isa<ConstantAsMetadata>(ExtraData) || isa<MDString>(ExtraData) ||
isa<DIObjCProperty>(ExtraData))
return true;
- if (auto *Tuple = dyn_cast<MDTuple>(ExtraData))
- return Tuple->getNumOperands() == 1 &&
- isa<ConstantAsMetadata>(Tuple->getOperand(0));
+ if (auto *Tuple = dyn_cast<MDTuple>(ExtraData)) {
+ if (N.getTag() != dwarf::DW_TAG_inheritance &&
+ N.getTag() != dwarf::DW_TAG_member &&
+ N.getTag() != dwarf::DW_TAG_variable)
+ return false;
+ if (Tuple->getNumOperands() != 1)
+ return false;
+ return isa_and_nonnull<ConstantAsMetadata>(Tuple->getOperand(0).get());
+ }
return false;
};
CheckDI(IsValidExtraData(),
diff --git a/llvm/test/Verifier/diderivedtype-extradata-tuple.ll b/llvm/test/Verifier/diderivedtype-extradata-tuple.ll
new file mode 100644
index 0000000000000..e3f7a46bf905b
--- /dev/null
+++ b/llvm/test/Verifier/diderivedtype-extradata-tuple.ll
@@ -0,0 +1,66 @@
+; RUN: not opt -S < %s 2>&1 | FileCheck %s
+
+;; Test that extraData with MDTuple is only allowed for specific DWARF tags:
+;; DW_TAG_inheritance, DW_TAG_member, and DW_TAG_variable
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+
+!1 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+
+; Keep all metadata nodes alive so verifier can check them
+!named = !{!1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19}
+!2 = !{i32 0}
+
+; Valid: DW_TAG_inheritance with tuple extraData should be accepted
+!3 = !DIDerivedType(tag: DW_TAG_inheritance, baseType: !1, size: 32, extraData: !2)
+
+; Valid: DW_TAG_member with tuple extraData should be accepted
+!4 = !DIDerivedType(tag: DW_TAG_member, name: "field", baseType: !1, size: 32, extraData: !2)
+
+; Valid: DW_TAG_variable (static member) with tuple extraData should be accepted
+!5 = !DIDerivedType(tag: DW_TAG_variable, name: "var", baseType: !1, extraData: !2, flags: DIFlagStaticMember)
+
+; Invalid: DW_TAG_typedef with tuple extraData should be rejected
+; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
+; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_typedef
+!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "IntTy", baseType: !1, extraData: !2)
+
+; Invalid: Empty tuple should be rejected
+!7 = !{}
+; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
+; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_member
+!8 = !DIDerivedType(tag: DW_TAG_member, name: "field2", baseType: !1, extraData: !7)
+
+; Invalid: Tuple with multiple operands should be rejected
+!9 = !{i32 0, i32 1}
+; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
+; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_member
+!10 = !DIDerivedType(tag: DW_TAG_member, name: "field3", baseType: !1, extraData: !9)
+
+; Invalid: Tuple with non-ConstantAsMetadata operand should be rejected
+!11 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+!12 = !{!11}
+; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
+; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_member
+!13 = !DIDerivedType(tag: DW_TAG_member, name: "field4", baseType: !1, extraData: !12)
+
+; Valid: ConstantAsMetadata as extraData should still work for any tag
+!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "IntTy2", baseType: !1, extraData: i32 42)
+
+; Valid: MDString as extraData should still work for any tag
+!15 = !DIDerivedType(tag: DW_TAG_typedef, name: "IntTy3", baseType: !1, extraData: !"some string")
+
+; Valid: DW_TAG_template_alias with proper template parameters tuple
+; Template aliases are handled specially and accept any MDTuple for template parameters
+!16 = !DITemplateTypeParameter(name: "T", type: !1)
+!17 = !{!16}
+!18 = !DIDerivedType(tag: DW_TAG_template_alias, name: "MyAlias", baseType: !1, extraData: !17)
+
+; Invalid: DW_TAG_template_alias with non-tuple extraData should fail
+; CHECK: invalid template parameters
+; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_template_alias
+!19 = !DIDerivedType(tag: DW_TAG_template_alias, name: "FailingAlias", baseType: !1, extraData: i32 42)
+
+; CHECK: warning: ignoring invalid debug info
+
>From bff5946e237945fab1d9d2bad289f107363a8c70 Mon Sep 17 00:00:00 2001
From: Laxman Sole <lsole at nvidia.com>
Date: Mon, 17 Nov 2025 10:54:09 -0800
Subject: [PATCH 3/3] updating verifier checks only for specific tags
---
llvm/lib/IR/Verifier.cpp | 11 +++---
.../Verifier/diderivedtype-extradata-tuple.ll | 35 +++++++------------
2 files changed, 18 insertions(+), 28 deletions(-)
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index c60f9c4808420..92e7b7530b038 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1324,16 +1324,17 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) {
} else if (N.getTag() == dwarf::DW_TAG_template_alias) {
CheckDI(isMDTuple(N.getRawExtraData()), "invalid template parameters", &N,
N.getRawExtraData());
- } else if (auto *ExtraData = N.getRawExtraData()) {
+ } else if (N.getTag() == dwarf::DW_TAG_inheritance ||
+ N.getTag() == dwarf::DW_TAG_member ||
+ N.getTag() == dwarf::DW_TAG_variable) {
+ auto *ExtraData = N.getRawExtraData();
auto IsValidExtraData = [&]() {
+ if (ExtraData == nullptr)
+ return true;
if (isa<ConstantAsMetadata>(ExtraData) || isa<MDString>(ExtraData) ||
isa<DIObjCProperty>(ExtraData))
return true;
if (auto *Tuple = dyn_cast<MDTuple>(ExtraData)) {
- if (N.getTag() != dwarf::DW_TAG_inheritance &&
- N.getTag() != dwarf::DW_TAG_member &&
- N.getTag() != dwarf::DW_TAG_variable)
- return false;
if (Tuple->getNumOperands() != 1)
return false;
return isa_and_nonnull<ConstantAsMetadata>(Tuple->getOperand(0).get());
diff --git a/llvm/test/Verifier/diderivedtype-extradata-tuple.ll b/llvm/test/Verifier/diderivedtype-extradata-tuple.ll
index e3f7a46bf905b..9258d1db76aff 100644
--- a/llvm/test/Verifier/diderivedtype-extradata-tuple.ll
+++ b/llvm/test/Verifier/diderivedtype-extradata-tuple.ll
@@ -9,7 +9,7 @@
!1 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
; Keep all metadata nodes alive so verifier can check them
-!named = !{!1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19}
+!named = !{!1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16}
!2 = !{i32 0}
; Valid: DW_TAG_inheritance with tuple extraData should be accepted
@@ -21,46 +21,35 @@
; Valid: DW_TAG_variable (static member) with tuple extraData should be accepted
!5 = !DIDerivedType(tag: DW_TAG_variable, name: "var", baseType: !1, extraData: !2, flags: DIFlagStaticMember)
-; Invalid: DW_TAG_typedef with tuple extraData should be rejected
-; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
-; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_typedef
-!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "IntTy", baseType: !1, extraData: !2)
-
; Invalid: Empty tuple should be rejected
-!7 = !{}
+!6 = !{}
; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_member
-!8 = !DIDerivedType(tag: DW_TAG_member, name: "field2", baseType: !1, extraData: !7)
+!7 = !DIDerivedType(tag: DW_TAG_member, name: "field2", baseType: !1, extraData: !6)
; Invalid: Tuple with multiple operands should be rejected
-!9 = !{i32 0, i32 1}
+!8 = !{i32 0, i32 1}
; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_member
-!10 = !DIDerivedType(tag: DW_TAG_member, name: "field3", baseType: !1, extraData: !9)
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "field3", baseType: !1, extraData: !8)
; Invalid: Tuple with non-ConstantAsMetadata operand should be rejected
-!11 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
-!12 = !{!11}
+!10 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+!11 = !{!10}
; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_member
-!13 = !DIDerivedType(tag: DW_TAG_member, name: "field4", baseType: !1, extraData: !12)
-
-; Valid: ConstantAsMetadata as extraData should still work for any tag
-!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "IntTy2", baseType: !1, extraData: i32 42)
-
-; Valid: MDString as extraData should still work for any tag
-!15 = !DIDerivedType(tag: DW_TAG_typedef, name: "IntTy3", baseType: !1, extraData: !"some string")
+!12 = !DIDerivedType(tag: DW_TAG_member, name: "field4", baseType: !1, extraData: !11)
; Valid: DW_TAG_template_alias with proper template parameters tuple
; Template aliases are handled specially and accept any MDTuple for template parameters
-!16 = !DITemplateTypeParameter(name: "T", type: !1)
-!17 = !{!16}
-!18 = !DIDerivedType(tag: DW_TAG_template_alias, name: "MyAlias", baseType: !1, extraData: !17)
+!13 = !DITemplateTypeParameter(name: "T", type: !1)
+!14 = !{!13}
+!15 = !DIDerivedType(tag: DW_TAG_template_alias, name: "MyAlias", baseType: !1, extraData: !14)
; Invalid: DW_TAG_template_alias with non-tuple extraData should fail
; CHECK: invalid template parameters
; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_template_alias
-!19 = !DIDerivedType(tag: DW_TAG_template_alias, name: "FailingAlias", baseType: !1, extraData: i32 42)
+!16 = !DIDerivedType(tag: DW_TAG_template_alias, name: "FailingAlias", baseType: !1, extraData: i32 42)
; CHECK: warning: ignoring invalid debug info
More information about the llvm-commits
mailing list