[llvm] 7a3bbf7 - [SelectionDAG] Fix null pointer dereference in resolveDanglingDebugInfo (#173500)

via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 28 10:00:51 PST 2025


Author: MetalOxideSemi
Date: 2025-12-28T18:00:46Z
New Revision: 7a3bbf724dc65ca959714bfd66b5e7ebf8c4e091

URL: https://github.com/llvm/llvm-project/commit/7a3bbf724dc65ca959714bfd66b5e7ebf8c4e091
DIFF: https://github.com/llvm/llvm-project/commit/7a3bbf724dc65ca959714bfd66b5e7ebf8c4e091.diff

LOG: [SelectionDAG] Fix null pointer dereference in resolveDanglingDebugInfo (#173500)

## Summary
Fix null pointer dereference in
`SelectionDAGBuilder::resolveDanglingDebugInfo`.

## Problem
`Val.getNode()->getIROrder()` is called before checking if
`Val.getNode()` is null, causing crashes when compiling code with debug
info that contains aggregate constants with nested empty structs.

## Solution
Move the `ValSDNodeOrder` declaration inside the `if (Val.getNode())`
block.

## Test Case
Reproduces with aggregate types containing nested empty structs:
```llvm
%3 = insertvalue { { i1, {} }, ptr, { { {} }, { {} } }, i64 } 
     { { i1, {} } zeroinitializer, ptr null, { { {} }, { {} } } zeroinitializer, i64 2 }, 
     ptr %2, 1, !dbg !893

## Crash stack
0.      Program arguments: llc-20 -O3 -mcpu=native -relocation-model=pic -filetype=obj /cloudide/workspace/temp/sf.ll -o /dev/null
1.      Running pass 'Function Pass Manager' on module '/cloudide/workspace/temp/sf.ll'.
2.      Running pass 'X86 DAG->DAG Instruction Selection' on function '@filter_create'
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  libLLVM.so.20.1 0x00007ff87ebbdf86 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 54
1  libLLVM.so.20.1 0x00007ff87ebbbb90 llvm::sys::RunSignalHandlers() + 80
2  libLLVM.so.20.1 0x00007ff87ebbe640
3  libpthread.so.0 0x00007ff87db79140
4  libLLVM.so.20.1 0x00007ff87f3fd2ff llvm::SelectionDAGBuilder::resolveDanglingDebugInfo(llvm::Value const*, llvm::SDValue) + 303
5  libLLVM.so.20.1 0x00007ff87f3fda5e llvm::SelectionDAGBuilder::getValue(llvm::Value const*) + 142
6  libLLVM.so.20.1 0x00007ff87f3fe79f llvm::SelectionDAGBuilder::getValueImpl(llvm::Value const*) + 3343
7  libLLVM.so.20.1 0x00007ff87f3fda34 llvm::SelectionDAGBuilder::getValue(llvm::Value const*) + 100
8  libLLVM.so.20.1 0x00007ff87f3fc1ab llvm::SelectionDAGBuilder::visitInsertValue(llvm::InsertValueInst const&) + 603
9  libLLVM.so.20.1 0x00007ff87f3eeaf7 llvm::SelectionDAGBuilder::visit(llvm::Instruction const&) + 327
10 libLLVM.so.20.1 0x00007ff87f4904b8 llvm::SelectionDAGISel::SelectBasicBlock(llvm::ilist_iterator_w_bits<llvm::ilist_detail::node_options<llvm::Instruction, false, false, void, true, llvm::BasicBlock>, false, true>, llvm::ilist_iterator_w_bits<llvm::ilist_detail::node_options<llvm::Instruction, false, false, void, true, llvm::BasicBlock>, false, true>, bool&) + 72
11 libLLVM.so.20.1 0x00007ff87f490304 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) + 5956
12 libLLVM.so.20.1 0x00007ff87f48e2b4 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 372
13 libLLVM.so.20.1 0x00007ff87f48c689 llvm::SelectionDAGISelLegacy::runOnMachineFunction(llvm::MachineFunction&) + 169
14 libLLVM.so.20.1 0x00007ff87efb8e32 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 610
15 libLLVM.so.20.1 0x00007ff87ed104be llvm::FPPassManager::runOnFunction(llvm::Function&) + 638
16 libLLVM.so.20.1 0x00007ff87ed15ff3 llvm::FPPassManager::runOnModule(llvm::Module&) + 51
17 libLLVM.so.20.1 0x00007ff87ed10c11 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 1105
18 llc-20          0x000055972ce77dc1 main + 9649
19 libc.so.6       0x00007ff87d68ad7a __libc_start_main + 234
20 llc-20          0x000055972ce7247a _start + 42

Added: 
    llvm/test/CodeGen/Generic/selectiondag-dbgvalue-null-crash.ll

Modified: 
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 9e342f9c4416f..e35c0d95f3941 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1504,7 +1504,6 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
   DanglingDebugInfoVector &DDIV = DanglingDbgInfoIt->second;
   for (auto &DDI : DDIV) {
     DebugLoc DL = DDI.getDebugLoc();
-    unsigned ValSDNodeOrder = Val.getNode()->getIROrder();
     unsigned DbgSDNodeOrder = DDI.getSDNodeOrder();
     DILocalVariable *Variable = DDI.getVariable();
     DIExpression *Expr = DDI.getExpression();
@@ -1518,6 +1517,7 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
       // in the first place we should not be more successful here). Unless we
       // have some test case that prove this to be correct we should avoid
       // calling EmitFuncArgumentDbgValue here.
+      unsigned ValSDNodeOrder = Val.getNode()->getIROrder();
       if (!EmitFuncArgumentDbgValue(V, Variable, Expr, DL,
                                     FuncArgumentDbgValueKind::Value, Val)) {
         LLVM_DEBUG(dbgs() << "Resolve dangling debug info for "

diff  --git a/llvm/test/CodeGen/Generic/selectiondag-dbgvalue-null-crash.ll b/llvm/test/CodeGen/Generic/selectiondag-dbgvalue-null-crash.ll
new file mode 100644
index 0000000000000..3ae8eed1392a6
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/selectiondag-dbgvalue-null-crash.ll
@@ -0,0 +1,34 @@
+; RUN: llc -O3 < %s
+;
+; Regression test for a null pointer dereference in 
+; SelectionDAG::resolveDanglingDebugInfo when Val.getNode() returns null
+; for aggregate types with nested empty structs.
+;
+; The crash occurred when:
+; 1. A dbg_value references an aggregate type containing empty structs {}
+; 2. An insertvalue operation on such types gets lowered by SelectionDAG
+; 3. The resulting SDValue has a null node, causing a crash when accessed
+
+define void @test() !dbg !4 {
+entry:
+  %tmp = alloca { { i1, {} }, ptr, { { {} }, { {} } }, i64 }, align 8
+    #dbg_value({ { {} }, { {} } } zeroinitializer, !5, !DIExpression(), !6)
+    #dbg_value(i64 2, !7, !DIExpression(), !6)
+  %0 = insertvalue { { i1, {} }, ptr, { { {} }, { {} } }, i64 } { { i1, {} } zeroinitializer, ptr null, { { {} }, { {} } } zeroinitializer, i64 2 }, ptr null, 1, !dbg !6
+  %1 = insertvalue { { i1, {} }, ptr, { { {} }, { {} } }, i64 } %0, { i1, {} } zeroinitializer, 0, !dbg !8
+  store { { i1, {} }, ptr, { { {} }, { {} } }, i64 } %1, ptr %tmp, align 8
+  ret void
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly)
+!1 = !DIFile(filename: "test_selectiondag.cpp", directory: "/home/AnonTokyo/documents/llvm-project/temp")
+!2 = !{i32 2, !"Debug Info Version", i32 3}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 1, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0)
+!5 = !DILocalVariable(name: "v1", scope: !4, file: !1, line: 2)
+!6 = !DILocation(line: 2, column: 1, scope: !4)
+!7 = !DILocalVariable(name: "v2", scope: !4, file: !1, line: 3)
+!8 = !DILocation(line: 3, column: 1, scope: !4)


        


More information about the llvm-commits mailing list