From dbd2f08dacf696b5ea1a9d21da28872883e3c2a9 Mon Sep 17 00:00:00 2001 From: Laxman Sole 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(N.getRawExtraData()), "invalid template parameters", + &N, N.getRawExtraData()); + } else if (auto *ExtraData = N.getRawExtraData()) { + auto IsValidExtraData = [&]() { + if (isa(ExtraData) || isa(ExtraData) || + isa(ExtraData)) + return true; + if (auto *Tuple = dyn_cast(ExtraData)) + return Tuple->getNumOperands() == 1 && + isa(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 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(MD); } static bool isScope(const Metadata *MD) { return !MD || isa(MD); } static bool isDINode(const Metadata *MD) { return !MD || isa(MD); } +static bool isMDTuple(const Metadata *MD) { return !MD || isa(MD); } void Verifier::visitDILocation(const DILocation &N) { CheckDI(N.getRawScope() && isa(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(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(ExtraData) || isa(ExtraData) || isa(ExtraData)) return true; - if (auto *Tuple = dyn_cast(ExtraData)) - return Tuple->getNumOperands() == 1 && - isa(Tuple->getOperand(0)); + if (auto *Tuple = dyn_cast(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(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 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(ExtraData) || isa(ExtraData) || isa(ExtraData)) return true; if (auto *Tuple = dyn_cast(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(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