This is the mail archive of the
mailing list for the GCC project.
Uninitialized memory access in final.c
- To: gcc-patches at gcc dot gnu dot org
- Subject: Uninitialized memory access in final.c
- From: Bernd Schmidt <bernds at redhat dot co dot uk>
- Date: Tue, 19 Sep 2000 15:45:03 +0100 (BST)
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.
* 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.
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)
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;