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

This program 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.

This program 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 GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, 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 "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 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;

static tree wfl;

#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 PARAMS ((tree, words, words, words));
static void check_init PARAMS ((tree, words));
static void check_cond_init PARAMS ((tree, tree, tree, words, words, words));
static void check_bool2_init PARAMS ((enum tree_code, tree, tree, words, words, words));
struct alternatives;
static void done_alternative PARAMS ((words, struct alternatives *));
static tree get_variable_decl PARAMS ((tree));
static void final_assign_error PARAMS ((tree));
static void check_final_reassigned PARAMS ((tree, words));

#define ALLOC_WORDS(NUM) ((word*) 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 (exp)
     tree 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;
	}
    }
  return NULL_TREE;
}

static void
final_assign_error (name)
     tree name;
{
  static const char format[]
    = "can't reassign a value to the final variable '%s'";
  parse_error_context (wfl, format, IDENTIFIER_POINTER (name));
}

static void
check_final_reassigned (decl, before)
     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. */
	  || ! 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 (test_exp, then_exp, else_exp,
		 before, when_false, when_true)
     tree test_exp, then_exp, else_exp;
     words before, when_false, 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 (code, exp0, exp1, before, when_false, when_true)
     enum tree_code code;  tree exp0, exp1;
     words before, when_false, 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 (exp, before, when_false, when_true)
     tree exp;
     words before, when_false, 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 MODIFY_EXPR:
      {
	tree tmp = TREE_OPERAND (exp, 0);
	if ((tmp = get_variable_decl (tmp)) != NULL_TREE)
	  {
	    int index;
	    check_bool_init (TREE_OPERAND (exp, 1), before,
			     when_false, when_true);
	    check_final_reassigned (tmp, before);
	    index = DECL_BIT_INDEX (tmp);
	    if (index >= 0)
	      {
		SET_ASSIGNED (when_false, index);
		SET_ASSIGNED (when_true, index);
		CLEAR_UNASSIGNED (when_false, index);
		CLEAR_UNASSIGNED (when_true, index);
	      }
	    break;
	  }
      }
      goto do_default;

    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:
    do_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 stucture.
   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 (after, current)
     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 (exp, before)
     tree exp;
     words before;
{
  tree tmp;
 again:
  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))
	    {
	      parse_error_context 
		(wfl, "Variable `%s' may not have been initialized",
		 IDENTIFIER_POINTER (DECL_NAME (exp)));
	      /* Suppress further errors. */
	      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))
	    {
	      parse_error_context 
		(wfl, "variable '%s' may not have been initialized",
		 IDENTIFIER_POINTER (DECL_NAME (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 */
	      && 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))))
		    hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
				 DECL_FUNCTION_INIT_TEST_CLASS(decl), TRUE, NULL);  
		}
	      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;
	return;
      }
    case EXIT_EXPR:
      {
	struct alternatives *alt = alternatives;
	DECLARE_BUFFERS(when_true, 2);
	words when_false = when_true + num_current_words;
#ifdef ENABLE_JC1_CHECKING
	if (TREE_CODE (alt->block) != LOOP_EXPR)
	  abort ();
#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);
	return;
      }
    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);
	return;
      }
    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);
	return;
      }
    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);
	return;
      }
    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);
      }
    return;

    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);
      }
      return;

    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);
      return;
      
    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 (exp == empty_stmt_node)
	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 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:
    case FFS_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));      

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

    case SAVE_EXPR:
      if (IS_INIT_CHECKED (exp))
	return;
      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:
    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 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 x = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
	for ( ;  x != NULL_TREE;  x = TREE_CHAIN (x))
	  check_init (TREE_VALUE (x), before);
      }
      break;

    case EXPR_WITH_FILE_LOCATION:
      {
	const char *saved_input_filename = input_filename;
	tree saved_wfl = wfl;
	tree body = EXPR_WFL_NODE (exp);
	int saved_lineno = lineno;
	if (body == empty_stmt_node)
	  break;
	wfl = exp;
	input_filename = EXPR_WFL_FILENAME (exp);
	lineno = EXPR_WFL_LINENO (exp);
	check_init (body, before);
	input_filename = saved_input_filename;
	lineno = saved_lineno;
	wfl = saved_wfl;
      }
      break;
      
    default:
      internal_error
	("internal error in check-init: tree code not implemented: %s",
	 tree_code_name [(int) TREE_CODE (exp)]);
    }
}

void
check_for_initialization (body, mdecl)
     tree body, 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_with_decl (decl, "final field '%s' may not have been initialized");
		}
	      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;
}

/* Call for every element in DECL_FUNCTION_INITIALIZED_CLASS_TABLE of
   a method to consider whether the type indirectly described by ENTRY
   is definitly initialized and thus remembered as such. */

bool
attach_initialized_static_class (entry, ptr)
     struct hash_entry *entry;
     PTR ptr;
{
  struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
  tree fndecl = DECL_CONTEXT (ite->init_test_decl);
  int index = DECL_BIT_INDEX (ite->init_test_decl);

  /* If the initializer flag has been definitly assigned (not taking
     into account its first mandatory assignment which has been
     already added but escaped analysis.) */
  if (fndecl && METHOD_STATIC (fndecl)
      && (DECL_INITIAL (ite->init_test_decl) == boolean_true_node
	  || (index >= 0 && ASSIGNED_P (((word *) ptr), index))))
    hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
		 entry->key, TRUE, NULL);
  return true;
}
