[llvm] [IR] Fix range-based for loop over MDOperands bug (PR #80737)

via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 5 12:11:47 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-debuginfo

Author: Shubham Sandeep Rastogi (rastogishubham)

<details>
<summary>Changes</summary>

With e8512786fedbfa6ddba70ceddc29d7122173ba5e the for loop that iterates over MDNode operands was changed to a range-based for loop. This change surfaces a bug where if the result of MD->operands() is an ArrayRef that has a size of 0, then iterating over that ArrayRef leads to a segmentation fault, due to accessing invalid addresses. This patch fixes that issue.

@<!-- -->kazutakahirata Please let me know if this patch works.

---
Full diff: https://github.com/llvm/llvm-project/pull/80737.diff


2 Files Affected:

- (modified) llvm/lib/IR/Verifier.cpp (+5-3) 
- (added) llvm/test/DebugInfo/verify-dwarf-no-operands.ll (+29) 


``````````diff
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 8d992c232ca7ce..54da5b299f1c93 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2912,9 +2912,11 @@ void Verifier::visitFunction(const Function &F) {
     for (auto &I : BB) {
       VisitDebugLoc(I, I.getDebugLoc().getAsMDNode());
       // The llvm.loop annotations also contain two DILocations.
-      if (auto MD = I.getMetadata(LLVMContext::MD_loop))
-        for (const MDOperand &MDO : llvm::drop_begin(MD->operands()))
-          VisitDebugLoc(I, dyn_cast_or_null<MDNode>(MDO));
+      if (auto MD = I.getMetadata(LLVMContext::MD_loop)) {
+        if (MD->getNumOperands())
+          for (const MDOperand &MDO : llvm::drop_begin(MD->operands()))
+            VisitDebugLoc(I, dyn_cast_or_null<MDNode>(MDO));
+      }
       if (BrokenDebugInfo)
         return;
     }
diff --git a/llvm/test/DebugInfo/verify-dwarf-no-operands.ll b/llvm/test/DebugInfo/verify-dwarf-no-operands.ll
new file mode 100644
index 00000000000000..c655289e9ee61e
--- /dev/null
+++ b/llvm/test/DebugInfo/verify-dwarf-no-operands.ll
@@ -0,0 +1,29 @@
+%"class.llvm::StringRef" = type { ptr, i64 }
+define internal void @_ZL30tokenizeWindowsCommandLineImplN4llvm9StringRefERNS_11StringSaverENS_12function_refIFvS0_EEEbNS3_IFvvEEEb() #0 !dbg !12 {
+  %7 = alloca %"class.llvm::StringRef", align 8
+  %21 = call noundef i64 @_ZNK4llvm9StringRef4sizeEv(ptr noundef nonnull align 8 dereferenceable(16) %7), !dbg !264
+  br label %22, !dbg !265
+  br label %22, !llvm.loop !284
+}
+define linkonce_odr noundef i64 @_ZNK4llvm9StringRef4sizeEv() #0 align 2 !dbg !340 {
+  %2 = alloca ptr, align 8
+  %3 = load ptr, ptr %2, align 8
+  %4 = getelementptr inbounds %"class.llvm::StringRef", ptr %3, !dbg !344
+  %5 = load i64, ptr %4, !dbg !344
+  ret i64 %5, !dbg !345
+}
+!llvm.module.flags = !{!2, !6}
+!llvm.dbg.cu = !{!7}
+!2 = !{i32 2, !"Debug Info Version", i32 3}
+!6 = !{i32 7, !"frame-pointer", i32 1}
+!7 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !8, sdk: "MacOSX14.0.sdk")
+!8 = !DIFile(filename: "file.cpp", directory: "/Users/Dev", checksumkind: CSK_MD5, checksum: "ed7ae158f20f7914bc5fb843291e80da")
+!12 = distinct !DISubprogram(unit: !7, retainedNodes: !36)
+!36 = !{}
+!260 = distinct !DILexicalBlock(scope: !12, line: 412, column: 3)
+!264 = !DILocation(scope: !260)
+!265 = !DILocation(scope: !260, column: 20)
+!284 = distinct !{}
+!340 = distinct !DISubprogram(unit: !7, retainedNodes: !36)
+!344 = !DILocation(scope: !340)
+!345 = !DILocation(scope: !340)

``````````

</details>


https://github.com/llvm/llvm-project/pull/80737


More information about the llvm-commits mailing list