]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gcc/java/check-init.c
Imported gcc-4.4.3
[msp430-gcc.git] / gcc / java / check-init.c
diff --git a/gcc/java/check-init.c b/gcc/java/check-init.c
deleted file mode 100644 (file)
index 6793533..0000000
+++ /dev/null
@@ -1,1025 +0,0 @@
-/* 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;
-}