diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -214,7 +214,9 @@ const RegisterLocations InitialLocs = Row.getRegisterLocations(); if (Error FdeError = UT.parseRows(Fde->cfis(), Row, &InitialLocs)) return std::move(FdeError); - UT.Rows.push_back(Row); + // Row will be empty if there are no CFI instructions. + if (!Cie->cfis().empty() || !Fde->cfis().empty()) + UT.Rows.push_back(Row); return UT; } @@ -223,7 +225,9 @@ UnwindRow Row; if (Error CieError = UT.parseRows(Cie->cfis(), Row, nullptr)) return std::move(CieError); - UT.Rows.push_back(Row); + // Row will be empty if there are no CFI instructions. + if (!Cie->cfis().empty()) + UT.Rows.push_back(Row); return UT; } diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp @@ -447,6 +447,45 @@ expectDumpResult(Locs, ""); } +// Here we test that empty rows are not added to UnwindTable when +// dwarf::CIE::CFIs or dwarf::FDE::CFIs is empty. +TEST(DWARFDebugFrame, UnwindTableEmptyRows) { + dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false, + /*Offset=*/0x0, + /*Length=*/0xff); + + // Having an empty instructions list is fine. + EXPECT_THAT_ERROR(parseCFI(TestCIE, {}), Succeeded()); + EXPECT_TRUE(TestCIE.cfis().empty()); + + // Verify dwarf::UnwindTable::create() won't result in errors and + // and empty rows are not added to CIE UnwindTable. + Expected RowsOrErr = dwarf::UnwindTable::create(&TestCIE); + EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded()); + const size_t ExpectedNumOfRows = 0; + EXPECT_EQ(RowsOrErr->size(), ExpectedNumOfRows); + + dwarf::FDE TestFDE(/*IsDWARF64=*/true, + /*Offset=*/0x3333abcdabcd, + /*Length=*/0x4444abcdabcd, + /*CIEPointer=*/0x1111abcdabcd, + /*InitialLocation=*/0x1000, + /*AddressRange=*/0x1000, + /*Cie=*/&TestCIE, + /*LSDAAddress=*/None, + /*Arch=*/Triple::x86_64); + + // Having an empty instructions list is fine. + EXPECT_THAT_ERROR(parseCFI(TestFDE, {}), Succeeded()); + EXPECT_TRUE(TestFDE.cfis().empty()); + + // Verify dwarf::UnwindTable::create() won't result in errors and + // and empty rows are not added to FDE UnwindTable. + RowsOrErr = dwarf::UnwindTable::create(&TestFDE); + EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded()); + EXPECT_EQ(RowsOrErr->size(), ExpectedNumOfRows); +} + TEST(DWARFDebugFrame, UnwindTableErrorNonAscendingFDERows) { dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false, /*Offset=*/0x0,