This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Uninitialized memory access in final.c


This showed up as a nonterminating compilation - the lengths of a few
branch insns kept oscillating.  Needless to say, it was rather dependent
on the commandline arguments (remove "-quiet" and it ceases to fail),
and not at all fun to track down.

The problem is that INSN_SHUID is only set for insns at the toplevel, i.e.
it's not set for anything in a SEQUENCE.  This means that the decision
in insn_current_reference_address whether the given branch is a forward
or a backward branch is essentially random.

While debugging this I also noticed that during the setup phase of
shorten_branches, insn_current_address is incremented twice for each
CODE_LABEL.  There's an increment in the continue arm of the enclosing
for statement, so it's not necessary to increment the variable in the
body of the loop.

Is it ever valid for an insn's length to be increased during shorten_branches?
It seems to me that this would cause the algorithm to be no longer guaranteed
to terminate.  If that's the case, we should probably check for it and abort
if it happens.


Bernd

	* final.c (insn_current_reference_address): Use INSN_SHUID of seq
	rather than that of branch.
	(shorten_branches): Don't increment insn_current_address twice.

Index: final.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/final.c,v
retrieving revision 1.198
diff -u -p -r1.198 final.c
--- final.c	2000/08/27 16:09:21	1.198
+++ final.c	2000/09/19 14:34:09
@@ -941,8 +941,9 @@ insn_current_reference_address (branch)
     return insn_current_address;
   dest = JUMP_LABEL (branch);
 
-  /* BRANCH has no proper alignment chain set, so use SEQ.  */
-  if (INSN_SHUID (branch) < INSN_SHUID (dest))
+  /* BRANCH has no proper alignment chain set, so use SEQ.  
+     BRANCH also has no INSN_SHUID.  */
+  if (INSN_SHUID (seq) < INSN_SHUID (dest))
     {
       /* Forward branch. */
       return (insn_last_address + insn_lengths[seq_uid]
@@ -1251,7 +1252,6 @@ shorten_branches (first)
 	      int align = 1 << log;
 	      int new_address = (insn_current_address + align - 1) & -align;
 	      insn_lengths[uid] = new_address - insn_current_address;
-	      insn_current_address = new_address;
 	    }
 	}
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]