[gcjx] Patch: FYI: definite assignment fix
Tom Tromey
tromey@redhat.com
Mon Jan 24 03:48:00 GMT 2005
I'm checking this in on the gcjx branch.
This fixes some bugs in definite assignment relating to how
try/finally is handled. This is good for 10 jacks failures.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* defassign.cc (join_state::pending_target): New structure.
(join_state::pending_pairs_type): Redefine.
(join_state::add_pending): Rewrote.
(join_state::abnormal_finally): Removed.
(join_state): Updated.
(definite_assignment_visitor::visit_try): Updated.
(definite_assignment_visitor::propagate_branch): Unconditionally
return when a 'try' is seen.
(variable_state::set_definite_assignment_from): New method.
Index: defassign.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/Attic/defassign.cc,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 defassign.cc
--- defassign.cc 13 Jan 2005 03:18:33 -0000 1.1.2.1
+++ defassign.cc 24 Jan 2005 03:46:32 -0000
@@ -1,6 +1,6 @@
// Definite assignment.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -126,6 +126,25 @@
assign = other.assign;
}
+ // This updates our state with the delta between FIRST and SECOND.
+ void set_definite_assignment_from (const variable_state &first,
+ const variable_state &second)
+ {
+ for (map_type::const_iterator i = second.assign.begin ();
+ i != second.assign.end ();
+ ++i)
+ {
+ if (! (*i).second)
+ continue;
+ map_type::const_iterator it = first.assign.find ((*i).first);
+ if (it != first.assign.end () && ! (*it).second)
+ {
+ assign[(*i).first] = true;
+ unassign[(*i).first] = false;
+ }
+ }
+ }
+
void insert (const model_variable_decl *decl, bool is_set = false)
{
assert (assign.find (decl) == assign.end ());
@@ -188,15 +207,19 @@
// True if the 'continue' state has been set.
bool is_continue_set;
- // True if this represents a 'try' statement where the 'finally'
- // cannot complete normally.
- bool abnormal_finally;
-
// All variable settings.
variable_state state;
variable_state continue_state;
- typedef std::multimap<model_stmt *, bool> pending_pairs_type;
+ // Used when considering pending targets.
+ struct pending_target
+ {
+ model_stmt *statement;
+ variable_state state;
+ bool is_continue;
+ };
+
+ typedef std::list<pending_target> pending_pairs_type;
// For 'try' statements we keep a list of all pending targets
// post-'finally'.
@@ -206,7 +229,6 @@
: statement (s),
has_continue (false),
is_continue_set (false),
- abnormal_finally (false),
state (init)
{
// We don't really want the state in 'init' -- we just want the
@@ -241,7 +263,11 @@
const variable_state &new_state)
{
merge (new_state);
- pending_pairs.insert (std::make_pair (target, is_continue));
+ pending_target targ;
+ targ.statement = target;
+ targ.state = new_state;
+ targ.is_continue = is_continue;
+ pending_pairs.push_back (targ);
}
variable_state &get_state ()
@@ -658,8 +684,6 @@
const ref_block &finally)
{
join_state save (trystmt, current);
- if (finally && ! finally->can_complete_normally ())
- save.abnormal_finally = true;
variable_state pre_statement = current;
// The state in SAVE is also touched by things like throw and
// return which propagate upward. We also need an accumulator
@@ -696,22 +720,22 @@
accum.merge_finally (current);
}
- current = accum;
+ // Propagate to all pending targets, but only if the finally
+ // clause completes normally.
+ if (! finally || finally->can_complete_normally ())
+ {
+ for (join_state::pending_pairs_type::const_iterator i
+ = save.pending_pairs.begin ();
+ i != save.pending_pairs.end ();
+ ++i)
+ {
+ current = (*i).state;
+ current.set_definite_assignment_from (save.get_state (), accum);
+ propagate_branch ((*i).statement, (*i).is_continue);
+ }
+ }
- // Propagate to all pending targets.
- // FIXME: at the moment this is handled by having the 'return' in
- // propagate_branch be conditional. But, that is wrong, since it
- // doesn't handle the case where a 'finally' clause sets a
- // variable and exits normally. One fix might be to track states
- // independently, then compute the variables that were made DA in
- // the finally, add them to the saved states, and propagate.
- // Then go back and merge all the saved states for the finally
- // computation.
-// for (join_state::pending_pairs_type::const_iterator i
-// = save.pending_pairs.begin ();
-// i != save.pending_pairs.end ();
-// ++i)
-// propagate_branch ((*i).first, (*i).second);
+ current = accum;
}
void visit_variable_stmt (model_variable_stmt *,
@@ -1508,15 +1532,15 @@
else
state->merge (current);
// We're done.
- return;
+ break;
}
- // See if we hit a 'try' statement.
+ // If we hit a 'try' statement, record the state as pending
+ // and handle it when processing the 'try'.
if (dynamic_cast<model_try *> (state->statement) != NULL)
{
state->add_pending (target, is_continue, current);
- if (state->abnormal_finally)
- return;
+ break;
}
}
}
More information about the Java-patches
mailing list