[LLVM-Reduce] - Null pointer handling during distinct metadata reduction (#117570)

Some distinct metadata nodes, e.g DICompileUnit, have implicit nullptrs
inside them. Iterating over them with dyn_cast leads to a crash, change
the behavior so that the nullptr operands are skipped.

Add the test distinct-metadata-nullptr.ll which will crash if null
pointers are not handled correctly.
This commit is contained in:
Robert Barinov
2024-11-25 23:20:45 +01:00
committed by GitHub
parent 1df34f1242
commit 0988bf8d75
2 changed files with 22 additions and 4 deletions

View File

@@ -0,0 +1,17 @@
; Test checking that distinct metadata reduction pass handles null pointers properly.
; This test will lead to a crash if nullptrs inside distinct metadata are not handled correctly, in this case inside DICompileUnit
; RUN: llvm-reduce --delta-passes=distinct-metadata --aggressive-named-md-reduction --test FileCheck --test-arg %s --test-arg --input-file %s -o %t
; CHECK: {{.*}}distinct !DICompileUnit{{.*}}
!llvm.module.flags = !{!0, !1, !6}
!llvm.dbg.cu = !{!4}
!0 = !{i32 7, !"Dwarf Version", i32 4}
!1 = !{i32 2, !"Source Lang Literal", !2}
!2 = !{!3}
!3 = !{!4, i32 33}
!4 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !5, producer: "foobar", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
!5 = !DIFile(filename: "main.cpp", directory: "foodir")
!6 = !{i32 2, !"Debug Info Version", i32 3}

View File

@@ -39,7 +39,7 @@ reduceNodes(MDNode *Root,
// Mark the nodes for removal
for (unsigned int I = 0; I < CurrentNode->getNumOperands(); ++I) {
if (MDNode *Operand =
dyn_cast<MDNode>(CurrentNode->getOperand(I).get())) {
dyn_cast_or_null<MDNode>(CurrentNode->getOperand(I).get())) {
// Check whether node has been visited
if (VisitedNodes.insert(Operand))
NodesToTraverse.push(Operand);
@@ -71,7 +71,7 @@ static void cleanUpTemporaries(NamedMDNode &NamedNode, MDTuple *TemporaryTuple,
for (auto I = NamedNode.op_begin(); I != NamedNode.op_end(); ++I) {
// If the node hasn't been traversed yet, add it to the queue of nodes to
// traverse.
if (MDTuple *TupleI = dyn_cast<MDTuple>((*I))) {
if (MDTuple *TupleI = dyn_cast_or_null<MDTuple>((*I))) {
if (VisitedNodes.insert(TupleI))
NodesToTraverse.push(TupleI);
}
@@ -108,7 +108,8 @@ static void cleanUpTemporaries(NamedMDNode &NamedNode, MDTuple *TemporaryTuple,
// Push the remaining nodes into the queue
for (unsigned int I = 0; I < CurrentTuple->getNumOperands(); ++I) {
MDTuple *Operand = dyn_cast<MDTuple>(CurrentTuple->getOperand(I).get());
MDTuple *Operand =
dyn_cast_or_null<MDTuple>(CurrentTuple->getOperand(I).get());
if (Operand && VisitedNodes.insert(Operand))
// If the node hasn't been traversed yet, add it to the queue of nodes
// to traverse.
@@ -127,7 +128,7 @@ static void extractDistinctMetadataFromModule(Oracle &O,
Program.named_metadata()) { // Iterate over the named nodes
for (unsigned int I = 0; I < NamedNode.getNumOperands();
++I) { // Iterate over first level unnamed nodes..
if (MDTuple *Operand = dyn_cast<MDTuple>(NamedNode.getOperand(I)))
if (MDTuple *Operand = dyn_cast_or_null<MDTuple>(NamedNode.getOperand(I)))
reduceNodes(Operand, NodesToDelete, TemporaryTuple, O, Program);
}
}