From 27f3de54874ab86bd53a50fc3f1b390273722ec9 Mon Sep 17 00:00:00 2001 From: Clark Coleman <clc@zephyr-software.com> Date: Tue, 25 Aug 2020 17:40:15 -0400 Subject: [PATCH] SPARK crash fixes. --- src/base/SMPFunction.cpp | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp index 15ff7959..05576858 100644 --- a/src/base/SMPFunction.cpp +++ b/src/base/SMPFunction.cpp @@ -12074,6 +12074,14 @@ void SMPFunction::FindGuardedLoops(void) { SMPBasicBlock *NextBlock = (*NextBlockIter); if (NextBlock->IsLoopHeaderBlock()) { // The less simple case: some [straight-line code] between COND_BRANCH and loop header. + + // To prevent being deceived by the case in which we fall through + // to the tail block, which the compiler has placed so that the tail block falls through + // to the loop header block, we require that the FallThroughBlock must dominate the loop + // header block. Simple, fast screening before concluding. + bool CorrectDomTreeStructure = this->DoesBlockDominateBlock((int) BlockIndex, NextBlock->GetNumber()); + if (!CorrectDomTreeStructure) + continue; // move on to next block FoundGuardedLoop = true; LoopAddr = NextBlock->GetFirstNonMarkerAddr(); } @@ -18125,7 +18133,7 @@ void SMPFunction::Dump(void) { if (this->LoopCount > 0) { SMP_msg("Block numbers by loop number:\n"); for (size_t LoopNum = 0; LoopNum < this->LoopCount; ++LoopNum) { - SMP_msg("Loop %d : ", LoopNum); + SMP_msg("Loop %d : Loop Type: %d :", LoopNum, this->LoopTypesByLoopNum[LoopNum]); for (size_t BlockNum = 0; BlockNum < (size_t)this->BlockCount; ++BlockNum) { if (this->FuncBlocksByLoop[LoopNum].GetBit(BlockNum)) { SMP_msg(" %zu", BlockNum); @@ -18796,6 +18804,13 @@ void SMPFunction::PreProcessForSPARKAdaTranslation(void) { } } size_t BlockNum = (size_t) CurrBlock->GetNumber(); + vector<SMPInstr *>::const_reverse_iterator LastInstIter = CurrBlock->GetRevInstCBegin(); + SMPInstr *LastInst = (*LastInstIter); + if (LastInst->IsBranchToOtherFunc()) { + SMP_msg("SPARK: WARNING: Bad CFG (branch outside function at %llx) \n", (uint64_t)LastInst->GetAddr()); + this->HasStructuredCFG = false; + } + if (HasLoops && CurrBlock->HasMemoryWrite() && this->IsBlockInAnyLoop((int) BlockNum)) { for (vector<SMPInstr *>::iterator InstIter = CurrBlock->GetFirstInst(); InstIter != CurrBlock->GetLastInst(); ++InstIter) { SMPInstr *CurrInst = (*InstIter); @@ -20217,7 +20232,7 @@ void SMPFunction::EmitFuncSPARKAda(void) { #else int FollowBlockNum = SMP_BLOCKNUM_UNINIT; #endif - this->EmitSPARKAdaForBlock(0, FollowBlockNum, BodyFile, false); + this->EmitSPARKAdaForBlock(0, FollowBlockNum, BodyFile, false, false); SMP_fprintf(BodyFile, "\nend %s;\n\n", AdaFuncName.c_str()); STARS_SPARK_IndentCount = 1; @@ -21636,8 +21651,10 @@ void SMPFunction::EmitSPARKAdaForBlock(int CurrBlockNum, int FollowBlockNum, FIL bool TranslatingGuardedLoop = (this->LoopToGuardMap.find(LoopAddr) != this->LoopToGuardMap.cend()); int NextFollowBlockNum = this->LoopFollowNodes[LoopNum]; // Could end with a loop if we call abort, etc., in which case no follow block. - // Otherwise, we should have a follow block. - assert((SMP_BLOCKNUM_UNINIT != NextFollowBlockNum) || (!this->FuncReturnsToCaller())); + // Could be an infinite loop. Otherwise, we should have a follow block. + bool FuncMightNotReturn = ((!this->FuncReturnsToCaller()) || this->HasCallToNonReturningFunc()); + bool LoopMightBeInfinite = (STARS_INFINITE_OR_MIDDLE_TESTING_LOOP == this->LoopTypesByLoopNum[LoopNum]); + assert((SMP_BLOCKNUM_UNINIT != NextFollowBlockNum) || FuncMightNotReturn || LoopMightBeInfinite); if (LoopToProc) { assert(TranslatingGuardedLoop || (ResumeBlockNum == NextFollowBlockNum)); // should be passed in as loop follow block number @@ -21761,7 +21778,7 @@ void SMPFunction::EmitSPARKAdaForBlock(int CurrBlockNum, int FollowBlockNum, FIL } else if (FlowType == JUMP) { // Get control flow type of the jump - assert(1 == CurrBlock->GetNumSuccessors()); + assert((1 == CurrBlock->GetNumSuccessors()) || LastInst->IsBranchToOtherFunc()); if (JUMP_INTO_LOOP_TEST == LastCFType) { // Optimized top-testing loop becomes a bottom-testing loop with a jump to the loop header/loop-test // block for the first iteration. We translate as a top-testing loop in Ada by starting with the @@ -21834,7 +21851,10 @@ void SMPFunction::EmitSPARKAdaForBlock(int CurrBlockNum, int FollowBlockNum, FIL ResumeBlockNum = FallThroughSucc->GetNumber(); } else { - assert(((FlowType == CALL) || (FlowType == HALT) || CurrBlock->IsUnreachableBlock()) && (0 == NumSuccessors)); + // Nop at end of block could be for alignment, masking the control flow type of CALL + // or HALT before it. + assert(((FlowType == CALL) || (FlowType == HALT) || CurrBlock->IsUnreachableBlock() || LastInst->IsNop()) + && (0 == NumSuccessors)); } } } // end if header block ... elsif tail block ... else ... -- GitLab