check-init.c 29.7 KB
Newer Older
1
/* Code to test for "definitive [un]assignment".
2
   Copyright (C) 1999, 2000, 2001  Free Software Foundation, Inc.
Per Bothner committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

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"
28
#include "flags.h" /* Needed for optimize. */
Per Bothner committed
29 30 31 32
#include "java-tree.h"
#include "toplev.h" /* Needed for fatal. */

/* The basic idea is that we assign each local variable declaration
33 34 35 36
   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 */
Per Bothner committed
37 38 39 40 41 42 43 44

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

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

/* Number of locals variables currently active. */
45 46 47 48 49
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;
Per Bothner committed
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

/* 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. */
71
static int start_current_locals = 0;
Per Bothner committed
72

73
static int num_current_words;
Per Bothner committed
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98

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)

99
#define WORD_SIZE  ((unsigned int)(sizeof(word) * BITS_PER_UNIT))
Per Bothner committed
100

101 102 103 104
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));
105
struct alternatives;
106
static void done_alternative PARAMS ((words, struct alternatives *));
107 108 109
static tree get_variable_decl PARAMS ((tree));
static void final_assign_error PARAMS ((tree));
static void check_final_reassigned PARAMS ((tree, words));
Per Bothner committed
110 111 112

#define ALLOC_WORDS(NUM) ((word*) xmalloc ((NUM) * sizeof (word)))
#define FREE_WORDS(PTR) (free (PTR))
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135

/* 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)
Per Bothner committed
136 137

#define SET_P(WORDS, BIT) \
138
  (WORDS[(BIT) / WORD_SIZE] & (1 << ((BIT) % WORD_SIZE)))
Per Bothner committed
139 140

#define CLEAR_BIT(WORDS, BIT) \
141
  (WORDS[(BIT) / WORD_SIZE] &= ~ (1 << ((BIT) % WORD_SIZE)))
Per Bothner committed
142 143

#define SET_BIT(WORDS, BIT) \
144
  (WORDS[(BIT) / WORD_SIZE] |= (1 << ((BIT) % WORD_SIZE)))
Per Bothner committed
145 146 147

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

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
#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[]
199
    = "can't reassign a value to the final variable '%s'";
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
  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));
    }
}

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

223
static void
Per Bothner committed
224 225 226 227 228
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;
{
229 230 231 232 233 234 235 236 237
  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;

Per Bothner committed
238 239 240 241 242
  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);
243 244
  RELEASE_BUFFERS(test_false);
  start_current_locals = save_start_current_locals;
Per Bothner committed
245 246 247
}

/* Check a boolean binary form CODE (EXP0, EXP1),
i  
Per Bothner committed
248
   where CODE is one of EQ_EXPR, BIT_AND_EXPR, or BIT_IOR_EXPR.
Per Bothner committed
249 250 251 252
   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)
i  
Per Bothner committed
253
     enum tree_code code;  tree exp0, exp1;
Per Bothner committed
254 255
     words before, when_false, when_true;
{
256 257
  word buf[2*4];
  words tmp = num_current_words <= 2 ? buf
Per Bothner committed
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
    : 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);
    }
291
  else if (code == BIT_AND_EXPR || code == TRUTH_AND_EXPR)
Per Bothner committed
292 293 294
    {
      UNION (when_true, when_true_0, when_true_1);
      INTERSECT (when_false, when_false_0, when_false_1);
i  
Per Bothner committed
295
      UNION (when_false, when_false, before);
Per Bothner committed
296
    }
297
  else /* if (code == BIT_IOR_EXPR || code == TRUTH_OR_EXPR) */
Per Bothner committed
298 299 300
    {
      UNION (when_false, when_false_0, when_false_1);
      INTERSECT (when_true, when_true_0, when_true_1);
i  
Per Bothner committed
301
      UNION (when_true, when_true, before);
Per Bothner committed
302 303 304 305 306 307
    }

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

308 309 310 311
/* 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
Per Bothner committed
312
   the conditional when the conditional is false.
313
   On output, WHEN_TRUE is the set of variables definitely [un]assigned after
Per Bothner committed
314
   the conditional when the conditional is true.
315
   (WHEN_FALSE and WHEN_TRUE are overwritten with initial values ignored.)
Per Bothner committed
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
   (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);
348
	if ((tmp = get_variable_decl (tmp)) != NULL_TREE)
Per Bothner committed
349 350 351 352
	  {
	    int index;
	    check_bool_init (TREE_OPERAND (exp, 1), before,
			     when_false, when_true);
353
	    check_final_reassigned (tmp, before);
Per Bothner committed
354 355 356
	    index = DECL_BIT_INDEX (tmp);
	    if (index >= 0)
	      {
357 358 359 360
		SET_ASSIGNED (when_false, index);
		SET_ASSIGNED (when_true, index);
		CLEAR_UNASSIGNED (when_false, index);
		CLEAR_UNASSIGNED (when_true, index);
Per Bothner committed
361 362 363 364 365 366 367
	      }
	    break;
	  }
      }
      goto do_default;

    case BIT_AND_EXPR:
i  
Per Bothner committed
368
    case BIT_IOR_EXPR:
369 370
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
Per Bothner committed
371 372 373 374 375 376
    case EQ_EXPR:
      check_bool2_init (TREE_CODE (exp),
			TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
			before, when_false, when_true);
      return;

377
    case TRUTH_XOR_EXPR:
Per Bothner committed
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
    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;

432 433 434 435
/* 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. */

Per Bothner committed
436 437 438 439 440 441 442 443 444 445 446 447 448
#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; \
}

449 450 451 452
/* 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. */

Per Bothner committed
453 454 455 456 457 458
static void
done_alternative (after, current)
     words after;
     struct alternatives *current; 
{
  INTERSECTN (current->combined, current->combined, after,
459
	      WORDS_NEEDED (2 * current->num_locals));
Per Bothner committed
460 461
}

462 463 464 465
/* 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. */

Per Bothner committed
466 467 468 469 470 471 472 473 474
#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; \
}

475
/* Check for (un)initialized local variables in EXP.  */
Per Bothner committed
476 477 478 479 480 481 482 483 484 485 486

static void
check_init (exp, before)
     tree exp;
     words before;
{
  tree tmp;
 again:
  switch (TREE_CODE (exp))
    {
    case VAR_DECL:
487 488 489
    case PARM_DECL:
      if (! FIELD_STATIC (exp) && DECL_NAME (exp) != NULL_TREE
	  && DECL_NAME (exp) != this_identifier_node)
Per Bothner committed
490 491
	{
	  int index = DECL_BIT_INDEX (exp);
492 493 494 495
	  /* 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))
Per Bothner committed
496
	    {
497 498 499
	      parse_error_context 
		(wfl, "Variable `%s' may not have been initialized",
		 IDENTIFIER_POINTER (DECL_NAME (exp)));
Per Bothner committed
500
	      /* Suppress further errors. */
501
	      DECL_BIT_INDEX (exp) = -2;
Per Bothner committed
502 503 504
	    }
	}
      break;
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521

    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;
      
Per Bothner committed
522 523
    case MODIFY_EXPR:
      tmp = TREE_OPERAND (exp, 0);
524 525
      /* We're interested in variable declaration and parameter
         declaration when they're declared with the `final' modifier. */
526
      if ((tmp = get_variable_decl (tmp)) != NULL_TREE)
Per Bothner committed
527 528 529
	{
	  int index;
	  check_init (TREE_OPERAND (exp, 1), before);
530
	  check_final_reassigned (tmp, before);
Per Bothner committed
531 532
	  index = DECL_BIT_INDEX (tmp);
	  if (index >= 0)
533 534 535 536
	    {
	      SET_ASSIGNED (before, index);
	      CLEAR_UNASSIGNED (before, index);
	    }
537 538 539 540 541
	  /* 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. */
542
	  if (! STATIC_CLASS_INIT_OPT_P () /* FIXME */
543
	      && index >= start_current_locals
Per Bothner committed
544 545 546 547 548 549 550
	      && index == num_current_locals - 1)
	    {
	      num_current_locals--;
	      DECL_BIT_INDEX (tmp) = -1;
	    }
	 break;
       }
551 552 553 554 555 556 557 558 559 560
      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;
	}
561
      else if (TREE_CODE (tmp) == COMPONENT_REF && IS_ARRAY_LENGTH_ACCESS (tmp))
562 563 564 565 566
	{
	  /* 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);
	}
Per Bothner committed
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
     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++;
	    }
583
	  words_needed = WORDS_NEEDED (2 * num_current_locals);
Per Bothner committed
584 585 586 587 588 589 590 591 592
	  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++)
593 594 595 596
	    {
	      CLEAR_ASSIGNED (tmp, i);
	      SET_UNASSIGNED (tmp, i);
	    }
Per Bothner committed
597
	  check_init (BLOCK_EXPR_BODY (exp), tmp);
598 599 600 601 602 603 604 605 606 607 608 609

	  /* 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))))
610 611 612 613
		    *(htab_find_slot 
		      (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
		       DECL_FUNCTION_INIT_TEST_CLASS (decl), INSERT)) =
		      DECL_FUNCTION_INIT_TEST_CLASS (decl);
614 615 616 617
		}
	      DECL_BIT_INDEX (decl) = -1;
	    }

Per Bothner committed
618 619 620 621 622 623 624 625 626 627 628 629
	  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:
      {
630 631 632 633 634 635 636 637 638
	/* 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. */

Per Bothner committed
639
	struct alternatives alt;
640 641 642 643
	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;
Per Bothner committed
644 645 646 647
	BEGIN_ALTERNATIVES (before, alt);
	alt.block = exp;
	check_init (TREE_OPERAND (exp, 0), before);
	END_ALTERNATIVES (before, alt);
648 649
	loop_current_locals = save_loop_current_locals;
	start_current_locals = save_start_current_locals;
Per Bothner committed
650 651 652 653 654
	return;
      }
    case EXIT_EXPR:
      {
	struct alternatives *alt = alternatives;
655 656
	DECLARE_BUFFERS(when_true, 2);
	words when_false = when_true + num_current_words;
657
#ifdef ENABLE_JC1_CHECKING
Per Bothner committed
658
	if (TREE_CODE (alt->block) != LOOP_EXPR)
659
	  abort ();
Per Bothner committed
660 661 662 663
#endif
	check_bool_init (TREE_OPERAND (exp, 0), before, when_false, when_true);
	done_alternative (when_true, alt);
	COPY (before, when_false);
664
	RELEASE_BUFFERS(when_true);
Per Bothner committed
665 666 667 668 669 670 671
	return;
      }
    case LABELED_BLOCK_EXPR:
      {
	struct alternatives alt;
	BEGIN_ALTERNATIVES (before, alt);
	alt.block = exp;
672 673
	if (LABELED_BLOCK_BODY (exp))
	  check_init (LABELED_BLOCK_BODY (exp), before);
Per Bothner committed
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690
	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;
691
	word buf[2];
Per Bothner committed
692 693
	check_init (TREE_OPERAND (exp, 0), before);
	BEGIN_ALTERNATIVES (before, alt);
694
	alt.saved = ALLOC_BUFFER(buf, num_current_words);
Per Bothner committed
695 696 697 698
	COPY (alt.saved, before);
	alt.block = exp;
	check_init (TREE_OPERAND (exp, 1), before);
	done_alternative (before, &alt);
699 700
	if (! SWITCH_HAS_DEFAULT (exp))
	  done_alternative (alt.saved, &alt);
701
	FREE_BUFFER(alt.saved, buf);
Per Bothner committed
702 703 704
	END_ALTERNATIVES (before, alt);
	return;
      }
705
    case CASE_EXPR:
706
    case DEFAULT_EXPR:
Per Bothner committed
707 708 709 710 711
      {
	int i;
	struct alternatives *alt = alternatives;
	while (TREE_CODE (alt->block) != SWITCH_EXPR)
	  alt = alt->outer;
712
	COPYN (before, alt->saved, WORDS_NEEDED (2 * alt->num_locals));
Per Bothner committed
713
	for (i = alt->num_locals;  i < num_current_locals;  i++)
714
	  CLEAR_ASSIGNED (before, i);
Per Bothner committed
715 716 717 718 719 720 721
	break;
      }

    case TRY_EXPR:
      {
	tree try_clause = TREE_OPERAND (exp, 0);
	tree clause = TREE_OPERAND (exp, 1);
722 723 724 725
	word buf[2*2];
	words tmp = (num_current_words <= 2 ? buf
		    : ALLOC_WORDS (2 * num_current_words));
	words save = tmp + num_current_words;
Per Bothner committed
726 727 728 729 730 731 732 733 734 735 736 737 738
	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);
	  }
739 740 741 742
	if (tmp != buf)
	  {
	    FREE_WORDS (tmp);
	  }
Per Bothner committed
743 744 745 746
	END_ALTERNATIVES (before, alt);
      }
    return;

747 748
    case TRY_FINALLY_EXPR:
      {
749
	DECLARE_BUFFERS(tmp, 1);
750
	COPY (tmp, before);
751 752 753
	check_init (TREE_OPERAND (exp, 0), before);
	check_init (TREE_OPERAND (exp, 1), tmp);
	UNION (before, before, tmp);
754
	RELEASE_BUFFERS(tmp);
755 756 757
      }
      return;

Per Bothner committed
758 759 760 761
    case RETURN_EXPR:
    case THROW_EXPR:
      if (TREE_OPERAND (exp, 0))
	check_init (TREE_OPERAND (exp, 0), before);
762
      goto never_continues;
Per Bothner committed
763 764

    case ERROR_MARK:
765
    never_continues:
Per Bothner committed
766
      SET_ALL (before);
767
      return;
Per Bothner committed
768 769 770 771 772
      
    case COND_EXPR:
    case TRUTH_ANDIF_EXPR:
    case TRUTH_ORIF_EXPR:
      {
773 774
	DECLARE_BUFFERS(when_true, 2);
	words when_false = when_true + num_current_words;
Per Bothner committed
775 776
	check_bool_init (exp, before, when_false, when_true);
	INTERSECT (before, when_false, when_true);
777
	RELEASE_BUFFERS(when_true);
Per Bothner committed
778 779
      }
      break;
780 781 782 783 784

    case NOP_EXPR:
      if (exp == empty_stmt_node)
	break;
      /* ... else fall through ... */
Per Bothner committed
785 786
    case UNARY_PLUS_EXPR:
    case NEGATE_EXPR:
787 788 789
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_XOR_EXPR:
Per Bothner committed
790 791 792
    case TRUTH_NOT_EXPR:
    case BIT_NOT_EXPR:
    case CONVERT_EXPR:
793
    case BIT_FIELD_REF:
Per Bothner committed
794 795 796 797 798 799
    case FLOAT_EXPR:
    case FIX_TRUNC_EXPR:
    case INDIRECT_REF:
    case ADDR_EXPR:
    case NON_LVALUE_EXPR:
    case INSTANCEOF_EXPR:
800 801 802 803 804
    case FIX_CEIL_EXPR:
    case FIX_FLOOR_EXPR:
    case FIX_ROUND_EXPR:
    case ABS_EXPR:
    case FFS_EXPR:
Per Bothner committed
805 806 807 808
      /* Avoid needless recursion. */
      exp = TREE_OPERAND (exp, 0);
      goto again;

809 810 811 812 813 814 815 816 817 818 819 820
    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;

821 822 823 824 825 826 827
    case SAVE_EXPR:
      if (IS_INIT_CHECKED (exp))
	return;
      IS_INIT_CHECKED (exp) = 1;
      exp = TREE_OPERAND (exp, 0);
      goto again;

Per Bothner committed
828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846
    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:
847
    case MAX_EXPR:
848
    case MIN_EXPR:
Per Bothner committed
849
    case ARRAY_REF:
850 851 852 853 854 855 856 857 858
    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:
Per Bothner committed
859 860 861 862 863 864 865 866 867 868 869
    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:
870
    case JAVA_EXC_OBJ_EXPR:
Per Bothner committed
871 872 873 874 875
      break;

    case NEW_CLASS_EXPR:
    case CALL_EXPR:
      {
876
	tree func = TREE_OPERAND (exp, 0);
Per Bothner committed
877
	tree x = TREE_OPERAND (exp, 1);
878 879 880 881
	if (TREE_CODE (func) == ADDR_EXPR)
	  func = TREE_OPERAND (func, 0);
	check_init (func, before);

Per Bothner committed
882 883
	for ( ;  x != NULL_TREE;  x = TREE_CHAIN (x))
	  check_init (TREE_VALUE (x), before);
884
	if (func == throw_node)
885
	  goto never_continues;
Per Bothner committed
886 887 888 889 890 891 892 893 894 895 896 897 898
      }
      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:
      {
Zack Weinberg committed
899
	const char *saved_input_filename = input_filename;
Per Bothner committed
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915
	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:
916 917 918
      internal_error
	("internal error in check-init: tree code not implemented: %s",
	 tree_code_name [(int) TREE_CODE (exp)]);
Per Bothner committed
919 920 921
    }
}

922 923 924
void
check_for_initialization (body, mdecl)
     tree body, mdecl;
Per Bothner committed
925
{
926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002
  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;
1003
}