[llvm] 58b8e6e - [DebugInfo][IR] Verifier checks for the extraData (#167971)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 18 11:33:44 PST 2025
Author: Laxman Sole
Date: 2025-11-18T14:33:40-05:00
New Revision: 58b8e6e4241ba71c8ffeef4578f1bebb9cec9db9
URL: https://github.com/llvm/llvm-project/commit/58b8e6e4241ba71c8ffeef4578f1bebb9cec9db9
DIFF: https://github.com/llvm/llvm-project/commit/58b8e6e4241ba71c8ffeef4578f1bebb9cec9db9.diff
LOG: [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
Added:
llvm/test/Verifier/diderivedtype-extradata-tuple.ll
Modified:
llvm/lib/IR/Verifier.cpp
Removed:
################################################################################
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index fa18c3cd0f404..92e7b7530b038 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()),
@@ -1320,6 +1321,30 @@ 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(isMDTuple(N.getRawExtraData()), "invalid template parameters", &N,
+ 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 (Tuple->getNumOperands() != 1)
+ return false;
+ return isa_and_nonnull<ConstantAsMetadata>(Tuple->getOperand(0).get());
+ }
+ 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) {
diff --git a/llvm/test/Verifier/diderivedtype-extradata-tuple.ll b/llvm/test/Verifier/diderivedtype-extradata-tuple.ll
new file mode 100644
index 0000000000000..9258d1db76aff
--- /dev/null
+++ b/llvm/test/Verifier/diderivedtype-extradata-tuple.ll
@@ -0,0 +1,55 @@
+; 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}
+!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: Empty tuple should be rejected
+!6 = !{}
+; CHECK: extraData must be ConstantAsMetadata, MDString, DIObjCProperty, or MDTuple with single ConstantAsMetadata operand
+; CHECK-NEXT: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_member
+!7 = !DIDerivedType(tag: DW_TAG_member, name: "field2", baseType: !1, extraData: !6)
+
+; Invalid: Tuple with multiple operands should be rejected
+!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
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "field3", baseType: !1, extraData: !8)
+
+; Invalid: Tuple with non-ConstantAsMetadata operand should be rejected
+!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
+!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
+!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
+!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