diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -608,6 +608,14 @@ ", which is unsupported. Assuming a value of 1 instead", LineTableOffset, OpcodeName.data(), OpcodeOffset, LineTable->Prologue.MaxOpsPerInst)); + if (ReportAdvanceAddrProblem && LineTable->Prologue.MinInstLength == 0) + ErrorHandler( + createStringError(errc::invalid_argument, + "line table program at offset 0x%8.8" PRIx64 + " contains a %s opcode at offset 0x%8.8" PRIx64 + ", but the prologue minimum_instruction_length value " + "is 0, which prevents any address advancing", + LineTableOffset, OpcodeName.data(), OpcodeOffset)); ReportAdvanceAddrProblem = false; uint64_t AddrOffset = OperationAdvance * LineTable->Prologue.MinInstLength; Row.Address.Address += AddrOffset; diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp @@ -1000,6 +1000,41 @@ Values(std::make_tuple(0, true), // Test zero value (error). std::make_tuple(14, false)), ); // Test non-zero value (no error). +struct BadMinInstLenFixture : public TestWithParam>, + public AdjustAddressFixtureBase { + void SetUp() override { + std::tie(MinInstLength, IsErrorExpected) = GetParam(); + } + + uint64_t editPrologue(LineTable <) override { + DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); + Prologue.MinInstLength = MinInstLength; + LT.setPrologue(Prologue); + return Prologue.TotalLength + Prologue.sizeofTotalLength(); + } + + uint64_t getAdjustedAddr(uint64_t Base, uint64_t ConstIncr, + uint64_t SpecialIncr, + uint64_t AdvanceIncr) override { + return MinInstLength != 0 ? AdjustAddressFixtureBase::getAdjustedAddr( + Base, ConstIncr, SpecialIncr, AdvanceIncr) + : Base; + } + + uint8_t MinInstLength; +}; + +TEST_P(BadMinInstLenFixture, MinInstLengthProblemsReportedCorrectly) { + runTest(/*CheckAdvancePC=*/true, + "but the prologue minimum_instruction_length value is 0, which " + "prevents any address advancing"); +} + +INSTANTIATE_TEST_CASE_P( + BadMinInstLenParams, BadMinInstLenFixture, + Values(std::make_tuple(0, true), // Test zero value (error). + std::make_tuple(1, false)), ); // Test non-zero value (no error). + TEST_F(DebugLineBasicFixture, ParserParsesCorrectly) { if (!setupGenerator()) return;