From: uz Date: Sat, 31 Oct 2009 10:36:59 +0000 (+0000) Subject: Fixed a problem with OptJumpTarget3. In a loop over all elements of a X-Git-Tag: V2.13.1~120 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=00a1121d8c504c5f466901c7712aff788dcbb389;p=cc65 Fixed a problem with OptJumpTarget3. In a loop over all elements of a collection that may remove something from the collection, we may not use an upcounting loop. git-svn-id: svn://svn.cc65.org/cc65/trunk@4409 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 1b6664029..d8446b892 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -801,12 +801,8 @@ unsigned OptJumpTarget3 (CodeSeg* S) I = 0; while (I < CS_GetEntryCount (S)) { - unsigned J, K; CodeEntry* N; - /* New jump label */ - CodeLabel* LN = 0; - /* Get next entry */ CodeEntry* E = CS_GetEntry (S, I); @@ -819,12 +815,23 @@ unsigned OptJumpTarget3 (CodeSeg* S) (N = CS_GetNextEntry (S, I)) != 0 && !CE_UseLoadFlags (N)) { + unsigned J; + int K; + + /* New jump label */ + CodeLabel* LN = 0; + /* Walk over all insn that jump here */ for (J = 0; J < CE_GetLabelCount (E); ++J) { /* Get the label */ CodeLabel* L = CE_GetLabel (E, J); - for (K = 0; K < CL_GetRefCount (L); ++K) { + + /* Loop over all insn that reference this label. Since we may + * eventually remove a reference in the loop, we must loop + * from end down to start. + */ + for (K = CL_GetRefCount (L) - 1; K >= 0; ++K) { /* Get the entry that jumps here */ CodeEntry* Jump = CL_GetRef (L, K); @@ -832,10 +839,12 @@ unsigned OptJumpTarget3 (CodeSeg* S) /* Get the register info from this insn */ short Val = RegVal (E->Chg, &Jump->RI->Out2); - /* Check if the outgoing value is the one thatr's loaded */ + /* Check if the outgoing value is the one thats's loaded */ if (Val == (unsigned char) E->Num) { - /* Ok, skip the insn. First, generate a label */ + /* Ok, skip the insn. First, generate a label for the + * next insn after E. + */ if (LN == 0) { LN = CS_GenLabel (S, N); }