/* Code to test for "definitive [un]assignment".
   Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006 Free Software Foundation,
   Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.  

Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
The Free Software Foundation is independent of Sun Microsystems, Inc.  */

/* Written by Per Bothner <bothner@cygnus.com>, January 1999. */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "flags.h" /* Needed for optimize. */
#include "java-tree.h"
#include "toplev.h" /* Needed for fatal. */

/* The basic idea is that we assign each local variable declaration
   and each blank final field an index, and then we pass around
   bitstrings, where the (2*i)'th bit is set if decl whose DECL_BIT_INDEX
   is i is definitely assigned, and the (2*i=1)'th bit is set if 
   decl whose DECL_BIT_INDEX is i is definitely unassigned */

/* One segment of a bitstring. */
typedef unsigned int word;

/* Pointer to a bitstring. */
typedef word *words;

/* Number of locals variables currently active. */
static int num_current_locals = 0;

/* The value of num_current_locals when we entered the closest
   enclosing LOOP_EXPR. */
static int loop_current_locals;

/* The index of the first local variable in the current block.

   The variables whose DECL_BIT_INDEX are in the range from
   start_current_locals (inclusive) up to num_current_locals (exclusive)
   are declared in the "current" block.  If there is a loop or branch
   form, we set start_current_locals to num_current_locals to indicate
   there is no current block.

   The point is that if a variable in the current block is set,
   there are no other control paths that we have to worry about.
   Hence, we can remove it from the set of variables we are
   checking, making its bit index available for some other variable.
   For simplicity, we only do that if the variable's bit index
   is (num_current_locals-1);  freeing up its bit index is then
   just a simple matter of decrementing num_current_locals.
   The reason this is worth doing is that it is simple, and
   allows us to use short (usually one-word) bit-strings,
   even for methods with thousands of local variables, as
   long as most of them are initialized immediately after or in
   their declaration. */
static int start_current_locals = 0;

static int num_current_words;

#define COPYN(DST, SRC, NWORDS) memcpy (DST, SRC, NWORDS * sizeof(word))
#define COPY(DST, SRC) COPYN (DST, SRC, num_current_words)

#define SET_ALL(DST) memset (DST, ~0, num_current_words * sizeof(word))
#define CLEAR_ALL(DST) memset (DST, 0, num_current_words * sizeof(word))

#define INTERSECTN(DST, SRC1, SRC2, N) \
  do { int n = N; \
  while (--n >= 0) DST[n] = SRC1[n] & SRC2[n]; \
  } while (0)

#define UNION(DST, SRC1, SRC2) \
  UNIONN (DST, SRC1, SRC2, num_current_words)

#define UNIONN(DST, SRC1, SRC2, N) \
  do { int n = N; \
  while (--n >= 0) DST[n] = SRC1[n] | SRC2[n]; \
  } while (0)

#define INTERSECT(DST, SRC1, SRC2) \
  INTERSECTN (DST, SRC1, SRC2, num_current_words)

#define WORD_SIZE  ((unsigned int)(sizeof(word) * BITS_PER_UNIT))

static void check_bool_init (tree, words, words, words);
static void check_init (tree, words);
static void check_cond_init (tree, tree, tree, words, words, words);
static void check_bool2_init (enum tree_code, tree, tree, words, words, words);
struct alternatives;
static void done_alternative (words, struct alternatives *);
static tree get_variable_decl (tree);
static void final_assign_error (tree);
static void check_final_reassigned (tree, words);

#define ALLOC_WORDS(NUM) (xmalloc ((NUM) * sizeof (word)))
#define FREE_WORDS(PTR) (free (PTR))

/* DECLARE_BUFFERS is used to allocate NUMBUFFER bit sets, each of
   which is an array of length num_current_words number of words.
   Declares a new local variable BUFFER to hold the result (or rather
   a pointer to the first of the bit sets).  In almost all cases
   num_current_words will be 1 or at most 2, so we try to stack
   allocate the arrays in that case, using a stack array
   named BUFFER##_short.  Each DECLARE_BUFFERS must be matched by
   a corresponding RELEASE_BUFFERS to avoid memory leaks.  */

#define DECLARE_BUFFERS(BUFFER, NUMBUFFERS) \
  word BUFFER##_short[2 * NUMBUFFERS]; \
  words BUFFER = ALLOC_BUFFER(BUFFER##_short, NUMBUFFERS * num_current_words)

#define RELEASE_BUFFERS(BUFFER) \
  FREE_BUFFER(BUFFER, BUFFER##_short)

#define ALLOC_BUFFER(SHORTBUFFER, NUMWORDS) \
  ((NUMWORDS) * sizeof(word) <= sizeof(SHORTBUFFER) ? SHORTBUFFER \
   : ALLOC_WORDS(NUMWORDS))

#define FREE_BUFFER(BUFFER, SHORTBUFFER) \
  if (BUFFER != SHORTBUFFER) FREE_WORDS(BUFFER)

#define SET_P(WORDS, BIT) \
  (WORDS[(BIT) / WORD_SIZE] & (1 << ((BIT) % WORD_SIZE)))

#define CLEAR_BIT(WORDS, BIT) \
  (WORDS[(BIT) / WORD_SIZE] &= ~ (1 << ((BIT) % WORD_SIZE)))

#define SET_BIT(WORDS, BIT) \
  (WORDS[(BIT) / WORD_SIZE] |= (1 << ((BIT) % WORD_SIZE)))

#define WORDS_NEEDED(BITS) (((BITS)+(WORD_SIZE-1))/(WORD_SIZE))

#define ASSIGNED_P(WORDS, BIT)  SET_P(WORDS, 2 * (BIT))
#define UNASSIGNED_P(WORDS, BIT)  SET_P(WORDS, 2 * (BIT) + 1)

#define SET_ASSIGNED(WORDS, INDEX) SET_BIT (WORDS, 2 * (INDEX))
#define SET_UNASSIGNED(WORDS, INDEX) SET_BIT (WORDS, 2 * (INDEX) + 1)

#define CLEAR_ASSIGNED(WORDS, INDEX) CLEAR_BIT (WORDS, 2 * (INDEX))
#define CLEAR_UNASSIGNED(WORDS, INDEX) CLEAR_BIT (WORDS, 2 * (INDEX) + 1)

/* Get the "interesting" declaration from a MODIFY_EXPR or COMPONENT_REF.
   Return the declaration or NULL_TREE if no interesting declaration.  */

static tree
get_variable_decl (tree exp)
{
  /* A static field can be wrapped in a COMPOUND_EXPR where the first
     argument initializes the class.  */
  if (TREE_CODE (exp) == COMPOUND_EXPR)
    exp = extract_field_decl (exp);

  if (TREE_CODE (exp) == VAR_DECL)
    {
      if (! TREE_STATIC (exp) ||  FIELD_FINAL (exp))
	return exp;
    }
  /* We only care about final parameters. */
  else if (TREE_CODE (exp) == PARM_DECL)
    {
      if (DECL_FINAL (exp))
	return exp;
    }
  /* See if exp is this.field. */
  else if (TREE_CODE (exp) == COMPONENT_REF)
    {
      tree op0 = TREE_OPERAND (exp, 0);
      tree op1 = TREE_OPERAND (exp, 1);
      tree mdecl = current_function_decl;
      if (TREE_CODE (op0) == INDIRECT_REF
	  && TREE_CODE (op1) == FIELD_DECL
	  && ! METHOD_STATIC (mdecl)
	  && FIELD_FINAL (op1))
	{
	  op0 = TREE_OPERAND (op0, 0);
	  if (op0 == BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)))
	    return op1;
	}
    }
  else if (TREE_CODE (exp) == INDIRECT_REF)
    {
      /* For indirect dispatch, look for an expression of the form 
      (indirect_ref (+ (array_ref otable <N>) this)).  
      FIXME: it would probably be better to generate a JAVA_FIELD_REF
      expression that gets converted to OTABLE access at
      gimplification time.  */
      exp = TREE_OPERAND (exp, 0);
      if (TREE_CODE (exp) == PLUS_EXPR)
	{
	  tree op0 = TREE_OPERAND (exp, 0);
	  STRIP_NOPS (op0);
	  if (TREE_CODE (op0) == ARRAY_REF)
	    {
	      tree table = TREE_OPERAND (op0, 0);
	      if (TREE_CODE (table) == VAR_DECL
		  && DECL_LANG_SPECIFIC (table)
		  && DECL_OWNER (table) 
		  && TYPE_OTABLE_DECL (DECL_OWNER (table)) == table)
		{
		  HOST_WIDE_INT index 
		    = TREE_INT_CST_LOW (TREE_OPERAND (op0, 1));
		  tree otable_methods 
		    = TYPE_OTABLE_METHODS (DECL_OWNER (table));
		  tree element;
		  for (element = otable_methods; 
		       element; 
		       element = TREE_CHAIN (element))
		    {
		      if (index == 1)
			{
			  tree purpose = TREE_PURPOSE (element);
			  if (TREE_CODE (purpose) == FIELD_DECL)
			    return purpose;
			  else
			    return NULL_TREE;
			}
		      --index;
		    }
		}
	    }
	}
    }

  return NULL_TREE;
}

static void
final_assign_error (tree name)
{
  error ("Can't reassign a value to the final variable %qs",
	 IDENTIFIER_POINTER (name));
}

static void
check_final_reassigned (tree decl, words before)
{
  int index = DECL_BIT_INDEX (decl);
  /* A final local already assigned or a final parameter
     assigned must be reported as errors */
  if (DECL_FINAL (decl) && index != -2
      && (index < loop_current_locals /* I.e. -1, or outside current loop. */
          || (DECL_LOCAL_FINAL_IUD (decl) ? ASSIGNED_P (before, index)
              : ! UNASSIGNED_P (before, index))))
    {
      final_assign_error (DECL_NAME (decl));
    }
}

/* Check a conditional form (TEST_EXP ? THEN_EXP : ELSE_EXP) for
   definite [un]assignment.
   BEFORE, WHEN_FALSE, and WHEN_TRUE are as in check_bool_init. */

static void
check_cond_init (tree test_exp, tree then_exp, tree else_exp,
		 words before, words when_false, words when_true)
{
  int save_start_current_locals = start_current_locals;
  DECLARE_BUFFERS(test_false, 6);
  words test_true = test_false + num_current_words;
  words then_false = test_true + num_current_words;
  words then_true = then_false + num_current_words;
  words else_false = then_true + num_current_words;
  words else_true = else_false + num_current_words;
  start_current_locals = num_current_locals;

  check_bool_init (test_exp, before, test_false, test_true);
  check_bool_init (then_exp, test_true, then_false, then_true);
  check_bool_init (else_exp, test_false, else_false, else_true);
  INTERSECT (when_false, then_false, else_false);
  INTERSECT (when_true, then_true, else_true);
  RELEASE_BUFFERS(test_false);
  start_current_locals = save_start_current_locals;
}

/* Check a boolean binary form CODE (EXP0, EXP1),
   where CODE is one of EQ_EXPR, BIT_AND_EXPR, or BIT_IOR_EXPR.
   BEFORE, WHEN_FALSE, and WHEN_TRUE are as in check_bool_init. */

static void
check_bool2_init (enum tree_code code, tree exp0, tree exp1,
		  words before, words when_false, words when_true)
{
  word buf[2*4];
  words tmp = num_current_words <= 2 ? buf
    : ALLOC_WORDS (4 * num_current_words);
  words when_false_0 = tmp;
  words when_false_1 = tmp+num_current_words;
  words when_true_0 = tmp+2*num_current_words;
  words when_true_1 = tmp+3*num_current_words;
  check_bool_init (exp0, before, when_false_0, when_true_0);
  INTERSECT (before, when_false_0, when_true_0);
  check_bool_init (exp1, before, when_false_1, when_true_1);

  INTERSECT (before, when_false_1, when_true_1);

  if (code == EQ_EXPR)
    {
      /* Now set:
       * when_true = (when_false_1 INTERSECTION when_true_1)
       *   UNION (when_true_0 INTERSECTION when_false_1)
       *   UNION (when_false_0 INTERSECTION when_true_1);
       * using when_false and before as temporary working areas.  */
      INTERSECT (when_true, when_true_0, when_false_1);
      INTERSECT (when_false, when_true_0, when_false_1);
      UNION (when_true, when_true, when_false);
      UNION (when_true, when_true, before);

      /* Now set:
       * when_false = (when_false_1 INTERSECTION when_true_1)
       *   UNION (when_true_0 INTERSECTION when_true_1)
       *   UNION (when_false_0 INTERSECTION when_false_1);
       * using before as a temporary working area.  */
      INTERSECT (when_false, when_true_0, when_true_1);
      UNION (when_false, when_false, before);
      INTERSECT (before, when_false_0, when_false_1);
      UNION (when_false, when_false, before);
    }
  else if (code == BIT_AND_EXPR || code == TRUTH_AND_EXPR)
    {
      UNION (when_true, when_true_0, when_true_1);
      INTERSECT (when_false, when_false_0, when_false_1);
      UNION (when_false, when_false, before);
    }
  else /* if (code == BIT_IOR_EXPR || code == TRUTH_OR_EXPR) */
    {
      UNION (when_false, when_false_0, when_false_1);
      INTERSECT (when_true, when_true_0, when_true_1);
      UNION (when_true, when_true, before);
    }

  if (tmp != buf)
    FREE_WORDS (tmp);
}

/* Check a boolean expression EXP for definite [un]assignment.
   BEFORE is the set of variables definitely [un]assigned before the
   conditional.  (This bitstring may be modified arbitrarily in this function.)
   On output, WHEN_FALSE is the set of variables [un]definitely assigned after
   the conditional when the conditional is false.
   On output, WHEN_TRUE is the set of variables definitely [un]assigned after
   the conditional when the conditional is true.
   (WHEN_FALSE and WHEN_TRUE are overwritten with initial values ignored.)
   (None of BEFORE, WHEN_FALSE, or WHEN_TRUE can overlap, as they may
   be used as temporary working areas. */

static void
check_bool_init (tree exp, words before, words when_false, words when_true)
{
  switch (TREE_CODE (exp))
    {
    case COND_EXPR:
      check_cond_init (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
		       TREE_OPERAND (exp, 2),
		       before, when_false, when_true);
      return;

    case TRUTH_ANDIF_EXPR:
      check_cond_init (TREE_OPERAND (exp, 0),
		       TREE_OPERAND (exp, 1), boolean_false_node,
		       before, when_false, when_true);
      return;
    case TRUTH_ORIF_EXPR:
      check_cond_init (TREE_OPERAND (exp, 0),
		       boolean_true_node, TREE_OPERAND (exp, 1),
		       before, when_false, when_true);
      return;
    case TRUTH_NOT_EXPR:
      check_bool_init (TREE_OPERAND (exp, 0), before, when_true, when_false);
      return;

    case BIT_AND_EXPR:
    case BIT_IOR_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case EQ_EXPR:
      check_bool2_init (TREE_CODE (exp),
			TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
			before, when_false, when_true);
      return;

    case TRUTH_XOR_EXPR:
    case BIT_XOR_EXPR:
    case NE_EXPR:
      /* Just like EQ_EXPR, but switch when_true and when_false. */
      check_bool2_init (EQ_EXPR, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
			before, when_true, when_false);

      return;

    case INTEGER_CST:
      if (integer_zerop (exp))
	{
	  SET_ALL (when_true);
	  COPY (when_false, before);
	}
      else
	{
	  SET_ALL (when_false);
	  COPY (when_true, before);
	}
      break;

    default:
      check_init (exp, before);
      COPY (when_false, before);
      COPY (when_true, before);
    }
}

/* Used to keep track of control flow branches. */

struct alternatives
{
  struct alternatives *outer;

  /* The value of num_current_locals at the start of this compound. */
  int num_locals;

  /* The value of the "before" set at the start of the control structure.
   Used for SWITCH_EXPR but not set for LABELED_BLOCK_EXPR. */
  words saved;

  int save_start_current_locals;

  /* If num_current_words==1, combined==&one_word, for efficiency. */
  word one_word;

  /* The intersection of the "after" sets from previous branches. */
  words combined;

  tree block;
};

struct alternatives * alternatives = NULL;

/* Begin handling a control flow branch.
   BEFORE is the state of [un]assigned variables on entry.
   CURRENT is a struct alt to manage the branch alternatives. */

#define BEGIN_ALTERNATIVES(before, current) \
{ \
  current.saved = NULL; \
  current.num_locals = num_current_locals; \
  current.combined = num_current_words <= 1 ? &current.one_word \
    : ALLOC_WORDS (num_current_words); \
  SET_ALL (current.combined); \
  current.outer = alternatives; \
  alternatives = &current; \
  current.save_start_current_locals = start_current_locals; \
  start_current_locals = num_current_locals; \
}

/* We have finished with one branch of branching control flow.
   Store the [un]assigned state, merging (intersecting) it with the state
   of previous alternative branches. */

static void
done_alternative (words after, struct alternatives *current)
{
  INTERSECTN (current->combined, current->combined, after,
	      WORDS_NEEDED (2 * current->num_locals));
}

/* Used when we done with a control flow branch and are all merged again.
 * AFTER is the merged state of [un]assigned variables,
   CURRENT is a struct alt that was passed to BEGIN_ALTERNATIVES. */

#define END_ALTERNATIVES(after, current) \
{ \
  alternatives = current.outer; \
  COPY (after, current.combined); \
  if (current.combined != &current.one_word) \
    FREE_WORDS (current.combined); \
  start_current_locals = current.save_start_current_locals; \
}

/* Check for (un)initialized local variables in EXP.  */

static void
check_init (tree exp, words before)
{
  tree tmp;
  location_t save_location = input_location;
 again:
  if (EXPR_HAS_LOCATION (exp))
    input_location = EXPR_LOCATION (exp);
  switch (TREE_CODE (exp))
    {
    case VAR_DECL:
    case PARM_DECL:
      if (! FIELD_STATIC (exp) && DECL_NAME (exp) != NULL_TREE
	  && DECL_NAME (exp) != this_identifier_node)
	{
	  int index = DECL_BIT_INDEX (exp);
	  /* We don't want to report and mark as non initialized class
	     initialization flags. */
	  if (! LOCAL_CLASS_INITIALIZATION_FLAG_P (exp)
	      && index >= 0 && ! ASSIGNED_P (before, index))
	    {
	      error ("variable %qD may not have been initialized", exp);
	      DECL_BIT_INDEX (exp) = -2;
	    }
	}
      break;

    case COMPONENT_REF:
      check_init (TREE_OPERAND (exp, 0), before);
      if ((tmp = get_variable_decl (exp)) != NULL_TREE)
	{
	  int index = DECL_BIT_INDEX (tmp);
	  if (index >= 0 && ! ASSIGNED_P (before, index))
	    {
	      error ("variable %qD may not have been initialized", tmp);
	      /* Suppress further errors. */
	      DECL_BIT_INDEX (tmp) = -2;
	    }
	}
      break;
      
    case MODIFY_EXPR:
      tmp = TREE_OPERAND (exp, 0);
      /* We're interested in variable declaration and parameter
         declaration when they're declared with the `final' modifier. */
      if ((tmp = get_variable_decl (tmp)) != NULL_TREE)
	{
	  int index;
	  check_init (TREE_OPERAND (exp, 1), before);
	  check_final_reassigned (tmp, before);
	  index = DECL_BIT_INDEX (tmp);
	  if (index >= 0)
	    {
	      SET_ASSIGNED (before, index);
	      CLEAR_UNASSIGNED (before, index);
	    }
	  /* Minor optimization.  See comment for start_current_locals.
	     If we're optimizing for class initialization, we keep
	     this information to check whether the variable is
	     definitely assigned when once we checked the whole
	     function. */
	  if (! STATIC_CLASS_INIT_OPT_P () /* FIXME */
	      && ! DECL_FINAL (tmp)
	      && index >= start_current_locals
	      && index == num_current_locals - 1)
	    {
	      num_current_locals--;
	      DECL_BIT_INDEX (tmp) = -1;
	    }
	 break;
       }
      else if (TREE_CODE (tmp = TREE_OPERAND (exp, 0)) == COMPONENT_REF)
	{
	  tree decl;
	  check_init (tmp, before);
	  check_init (TREE_OPERAND (exp, 1), before);
	  decl = TREE_OPERAND (tmp, 1);
	  if (DECL_FINAL (decl))
	    final_assign_error (DECL_NAME (decl));
	  break;
	}
      else if (TREE_CODE (tmp) == COMPONENT_REF && IS_ARRAY_LENGTH_ACCESS (tmp))
	{
	  /* We can't emit a more specific message here, because when
	     compiling to bytecodes we don't get here. */
	  final_assign_error (length_identifier_node);
	}
     else
       goto binop;
    case BLOCK:
      if (BLOCK_EXPR_BODY (exp))
	{
	  tree decl = BLOCK_EXPR_DECLS (exp);
	  int words_needed;
	  word* tmp;
	  int i;
	  int save_start_current_locals = start_current_locals;
	  int save_num_current_words = num_current_words;
	  start_current_locals = num_current_locals;
	  for (;  decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	    {
	      DECL_BIT_INDEX (decl) = num_current_locals++;
	    }
	  words_needed = WORDS_NEEDED (2 * num_current_locals);
	  if (words_needed > num_current_words)
	    {
	      tmp = ALLOC_WORDS (words_needed);
	      COPY (tmp, before);
	      num_current_words = words_needed;
	    }
	  else
	    tmp = before;
	  for (i = start_current_locals;  i < num_current_locals;  i++)
	    {
	      CLEAR_ASSIGNED (tmp, i);
	      SET_UNASSIGNED (tmp, i);
	    }
	  check_init (BLOCK_EXPR_BODY (exp), tmp);

	  /* Re-set DECL_BIT_INDEX since it is also DECL_POINTER_ALIAS_SET. */
	  for (decl = BLOCK_EXPR_DECLS (exp);
	       decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	    {
	      if (LOCAL_CLASS_INITIALIZATION_FLAG_P (decl))
		{
		  int index = DECL_BIT_INDEX (decl);
		  tree fndecl = DECL_CONTEXT (decl);
		  if (fndecl && METHOD_STATIC (fndecl)
		      && (DECL_INITIAL (decl) == boolean_true_node
			  || (index >= 0 && ASSIGNED_P (tmp, index))))
		    *(htab_find_slot 
		      (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
		       DECL_FUNCTION_INIT_TEST_CLASS (decl), INSERT)) =
		      DECL_FUNCTION_INIT_TEST_CLASS (decl);
		}
	      DECL_BIT_INDEX (decl) = -1;
	    }

	  num_current_locals = start_current_locals;
	  start_current_locals = save_start_current_locals;
	  if (tmp != before)
	    {
	      num_current_words = save_num_current_words;
	      COPY (before, tmp);
	      FREE_WORDS (tmp);
	    }
	}
      break;
    case LOOP_EXPR:
      {
	/* The JLS 2nd edition discusses a complication determining
	   definite unassignment of loop statements.  They define a
	   "hypothetical" analysis model.  We do something much
	   simpler: We just disallow assignments inside loops to final
	   variables declared outside the loop.  This means we may
	   disallow some contrived assignments that the JLS, but I
	   can't see how anything except a very contrived testcase (a
	   do-while whose condition is false?) would care. */

	struct alternatives alt;
	int save_loop_current_locals = loop_current_locals;
	int save_start_current_locals = start_current_locals;
	loop_current_locals = num_current_locals;
	start_current_locals = num_current_locals;
	BEGIN_ALTERNATIVES (before, alt);
	alt.block = exp;
	check_init (TREE_OPERAND (exp, 0), before);
	END_ALTERNATIVES (before, alt);
	loop_current_locals = save_loop_current_locals;
	start_current_locals = save_start_current_locals;
	break;
      }
    case EXIT_EXPR:
      {
	struct alternatives *alt = alternatives;
	DECLARE_BUFFERS(when_true, 2);
	words when_false = when_true + num_current_words;
#ifdef ENABLE_JC1_CHECKING
	gcc_assert (TREE_CODE (alt->block) == LOOP_EXPR);
#endif
	check_bool_init (TREE_OPERAND (exp, 0), before, when_false, when_true);
	done_alternative (when_true, alt);
	COPY (before, when_false);
	RELEASE_BUFFERS(when_true);
	break;
      }
    case LABELED_BLOCK_EXPR:
      {
	struct alternatives alt;
	BEGIN_ALTERNATIVES (before, alt);
	alt.block = exp;
	if (LABELED_BLOCK_BODY (exp))
	  check_init (LABELED_BLOCK_BODY (exp), before);
	done_alternative (before, &alt);
	END_ALTERNATIVES (before, alt);
	break;
      }
    case EXIT_BLOCK_EXPR:
      {
	tree block = TREE_OPERAND (exp, 0);
	struct alternatives *alt = alternatives;
	while (alt->block != block)
	  alt = alt->outer;
	done_alternative (before, alt);
	SET_ALL (before);
	break;
      }
    case SWITCH_EXPR:
      {
	struct alternatives alt;
	word buf[2];
	check_init (TREE_OPERAND (exp, 0), before);
	BEGIN_ALTERNATIVES (before, alt);
	alt.saved = ALLOC_BUFFER(buf, num_current_words);
	COPY (alt.saved, before);
	alt.block = exp;
	check_init (TREE_OPERAND (exp, 1), before);
	done_alternative (before, &alt);
	if (! SWITCH_HAS_DEFAULT (exp))
	  done_alternative (alt.saved, &alt);
	FREE_BUFFER(alt.saved, buf);
	END_ALTERNATIVES (before, alt);
	break;
      }
    case CASE_EXPR:
    case DEFAULT_EXPR:
      {
	int i;
	struct alternatives *alt = alternatives;
	while (TREE_CODE (alt->block) != SWITCH_EXPR)
	  alt = alt->outer;
	COPYN (before, alt->saved, WORDS_NEEDED (2 * alt->num_locals));
	for (i = alt->num_locals;  i < num_current_locals;  i++)
	  CLEAR_ASSIGNED (before, i);
	break;
      }

    case TRY_EXPR:
      {
	tree try_clause = TREE_OPERAND (exp, 0);
	tree clause = TREE_OPERAND (exp, 1);
	word buf[2*2];
	words tmp = (num_current_words <= 2 ? buf
		    : ALLOC_WORDS (2 * num_current_words));
	words save = tmp + num_current_words;
	struct alternatives alt;
	BEGIN_ALTERNATIVES (before, alt);
	COPY (save, before);
	COPY (tmp, save);
	check_init (try_clause, tmp);
	done_alternative (tmp, &alt);
	for ( ; clause != NULL_TREE;  clause = TREE_CHAIN (clause))
	  {
	    tree catch_clause = TREE_OPERAND (clause, 0);
	    COPY (tmp, save);
	    check_init (catch_clause, tmp);
	    done_alternative (tmp, &alt);
	  }
	if (tmp != buf)
	  {
	    FREE_WORDS (tmp);
	  }
	END_ALTERNATIVES (before, alt);
      }
    break;

    case TRY_FINALLY_EXPR:
      {
	DECLARE_BUFFERS(tmp, 1);
	COPY (tmp, before);
	check_init (TREE_OPERAND (exp, 0), before);
	check_init (TREE_OPERAND (exp, 1), tmp);
	UNION (before, before, tmp);
	RELEASE_BUFFERS(tmp);
      }
      break;

    case RETURN_EXPR:
    case THROW_EXPR:
      if (TREE_OPERAND (exp, 0))
	check_init (TREE_OPERAND (exp, 0), before);
      goto never_continues;

    case ERROR_MARK:
    never_continues:
      SET_ALL (before);
      break;
      
    case COND_EXPR:
    case TRUTH_ANDIF_EXPR:
    case TRUTH_ORIF_EXPR:
      {
	DECLARE_BUFFERS(when_true, 2);
	words when_false = when_true + num_current_words;
	check_bool_init (exp, before, when_false, when_true);
	INTERSECT (before, when_false, when_true);
	RELEASE_BUFFERS(when_true);
      }
      break;

    case NOP_EXPR:
      if (IS_EMPTY_STMT (exp))
	break;
      /* ... else fall through ... */
    case UNARY_PLUS_EXPR:
    case NEGATE_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_XOR_EXPR:
    case TRUTH_NOT_EXPR:
    case BIT_NOT_EXPR:
    case CONVERT_EXPR:
    case VIEW_CONVERT_EXPR:
    case BIT_FIELD_REF:
    case FLOAT_EXPR:
    case FIX_TRUNC_EXPR:
    case INDIRECT_REF:
    case ADDR_EXPR:
    case NON_LVALUE_EXPR:
    case INSTANCEOF_EXPR:
    case FIX_CEIL_EXPR:
    case FIX_FLOOR_EXPR:
    case FIX_ROUND_EXPR:
    case ABS_EXPR:
      /* Avoid needless recursion. */
      exp = TREE_OPERAND (exp, 0);
      goto again;

    case PREDECREMENT_EXPR:
    case PREINCREMENT_EXPR:
    case POSTDECREMENT_EXPR:
    case POSTINCREMENT_EXPR:
      tmp = get_variable_decl (TREE_OPERAND (exp, 0));
      if (tmp != NULL_TREE && DECL_FINAL (tmp))
	final_assign_error (DECL_NAME (tmp));
      else if (TREE_CODE (tmp = TREE_OPERAND (exp, 0)) == COMPONENT_REF)
        {
          /* Take care of array length accesses too.  */
          tree decl = TREE_OPERAND (tmp, 1);
          if (DECL_FINAL (decl))
            final_assign_error (DECL_NAME (decl));
        }

      /* Avoid needless recursion.  */
      exp = TREE_OPERAND (exp, 0);
      goto again;

    case SAVE_EXPR:
      if (IS_INIT_CHECKED (exp))
	break;
      IS_INIT_CHECKED (exp) = 1;
      exp = TREE_OPERAND (exp, 0);
      goto again;

    case COMPOUND_EXPR:
    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
    case TRUNC_DIV_EXPR:
    case TRUNC_MOD_EXPR:
    case RDIV_EXPR:
    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case URSHIFT_EXPR:
    case BIT_AND_EXPR:
    case BIT_XOR_EXPR:
    case BIT_IOR_EXPR:
    case EQ_EXPR: 
    case NE_EXPR:
    case GT_EXPR:
    case GE_EXPR:
    case LT_EXPR:
    case LE_EXPR:
    case MAX_EXPR:
    case MIN_EXPR:
    case ARRAY_REF:
    case LROTATE_EXPR:
    case RROTATE_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case CEIL_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case EXACT_DIV_EXPR:
    case UNLT_EXPR:
    case UNLE_EXPR:
    case UNGT_EXPR:
    case UNGE_EXPR:
    case UNEQ_EXPR:
    case LTGT_EXPR:
    binop:
      check_init (TREE_OPERAND (exp, 0), before);
      /* Avoid needless recursion, especially for COMPOUND_EXPR. */
      exp = TREE_OPERAND (exp, 1);
      goto again;

    case RESULT_DECL:
    case FUNCTION_DECL:
    case INTEGER_CST:
    case REAL_CST:
    case STRING_CST:
    case DECL_EXPR:
    case JAVA_EXC_OBJ_EXPR:
      break;

    case NEW_CLASS_EXPR:
    case CALL_EXPR:
      {
	tree func = TREE_OPERAND (exp, 0);
	tree x = TREE_OPERAND (exp, 1);
	if (TREE_CODE (func) == ADDR_EXPR)
	  func = TREE_OPERAND (func, 0);
	check_init (func, before);

	for ( ;  x != NULL_TREE;  x = TREE_CHAIN (x))
	  check_init (TREE_VALUE (x), before);
	if (func == throw_node)
	  goto never_continues;
      }
      break;

    case NEW_ARRAY_INIT:
      {
	tree value;
	unsigned HOST_WIDE_INT idx;
	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)),
				    idx, value)
	  check_init (value, before);
      }
      break;

    case EXPR_WITH_FILE_LOCATION:
      {
	location_t saved_location = input_location;
	tree body = EXPR_WFL_NODE (exp);
	if (IS_EMPTY_STMT (body))
	  break;
#ifdef USE_MAPPED_LOCATION
	input_location = EXPR_LOCATION (exp);
#else
	input_filename = EXPR_WFL_FILENAME (exp);
	input_line = EXPR_WFL_LINENO (exp);
#endif
	check_init (body, before);
	input_location = saved_location;
      }
      break;
      
    default:
      internal_error
	("internal error in check-init: tree code not implemented: %s",
	 tree_code_name [(int) TREE_CODE (exp)]);
    }
  input_location = save_location;
}

void
check_for_initialization (tree body, tree mdecl)
{
  tree decl;
  word buf[2];
  words before = buf;
  tree owner = DECL_CONTEXT (mdecl);
  int is_static_method = METHOD_STATIC (mdecl);
  /* We don't need to check final fields of <init> it it calls this(). */
  int is_finit_method = DECL_FINIT_P (mdecl) || DECL_INSTINIT_P (mdecl);
  int is_init_method
    = (is_finit_method || DECL_CLINIT_P (mdecl)
       || (DECL_INIT_P (mdecl) && ! DECL_INIT_CALLS_THIS (mdecl)));

  start_current_locals = num_current_locals = 0;
  num_current_words = 2;

  if (is_init_method)
    {
      int words_needed, i;
      for (decl = TYPE_FIELDS (owner);
	   decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	{
	  if (DECL_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
	    {
	      if (DECL_FIELD_FINAL_IUD (decl))
		DECL_BIT_INDEX (decl) = -1;
	      else
		DECL_BIT_INDEX (decl) = num_current_locals++;
	    }
	}
      words_needed = WORDS_NEEDED (2 * num_current_locals);
      if (words_needed > 2)
	{
	  num_current_words = words_needed;
	  before = ALLOC_WORDS(words_needed);
	}
      i = 0;
      for (decl = TYPE_FIELDS (owner);
	   decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	{
	  if (FIELD_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
	    {
	      if (! DECL_FIELD_FINAL_IUD (decl))
		{
		  CLEAR_ASSIGNED (before, i);
		  SET_UNASSIGNED (before, i);
		  i++;
		}
	    }
	}

    }

  check_init (body, before);

  if (is_init_method)
    {
      for (decl = TYPE_FIELDS (owner);
	   decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	{
	  if (FIELD_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
	    {
	      int index = DECL_BIT_INDEX (decl);
	      if (index >= 0 && ! ASSIGNED_P (before, index))
		{
		  if (! is_finit_method)
		    error ("%Jfinal field %qD may not have been initialized",
                           decl, decl);
		}
	      else if (is_finit_method)
		DECL_FIELD_FINAL_IUD (decl) = 1;

	      /* Re-set to initial state, since we later may use the
		 same bit for DECL_POINTER_ALIAS_SET. */
	      DECL_BIT_INDEX (decl) = -1;
	    }
	}
    }

  start_current_locals = num_current_locals = 0;
}
