]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/java/check-init.c
Merge tree-ssa-20020619-branch into mainline.
[thirdparty/gcc.git] / gcc / java / check-init.c
CommitLineData
4f88ccda 1/* Code to test for "definitive [un]assignment".
f309ff0a 2 Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
4ba9a1aa 3
f309ff0a
SB
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
4ba9a1aa
PB
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
f309ff0a 11GCC is distributed in the hope that it will be useful,
4ba9a1aa
PB
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
f309ff0a 17along with GCC; see the file COPYING. If not, write to
4ba9a1aa
PB
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.
20
21Java and all Java-based marks are trademarks or registered trademarks
22of Sun Microsystems, Inc. in the United States and other countries.
23The Free Software Foundation is independent of Sun Microsystems, Inc. */
24
25/* Written by Per Bothner <bothner@cygnus.com>, January 1999. */
26
27#include "config.h"
28#include "system.h"
4977bab6
ZW
29#include "coretypes.h"
30#include "tm.h"
4ba9a1aa 31#include "tree.h"
4009bb7d 32#include "flags.h" /* Needed for optimize. */
4ba9a1aa
PB
33#include "java-tree.h"
34#include "toplev.h" /* Needed for fatal. */
35
36/* The basic idea is that we assign each local variable declaration
4f88ccda
PB
37 and each blank final field an index, and then we pass around
38 bitstrings, where the (2*i)'th bit is set if decl whose DECL_BIT_INDEX
39 is i is definitely assigned, and the the (2*i=1)'th bit is set if
40 decl whose DECL_BIT_INDEX is i is definitely unassigned */
4ba9a1aa
PB
41
42/* One segment of a bitstring. */
43typedef unsigned int word;
44
45/* Pointer to a bitstring. */
46typedef word *words;
47
4ba9a1aa 48/* Number of locals variables currently active. */
4f88ccda
PB
49static int num_current_locals = 0;
50
51/* The value of num_current_locals when we entered the closest
52 enclosing LOOP_EXPR. */
53static int loop_current_locals;
4ba9a1aa
PB
54
55/* The index of the first local variable in the current block.
56
57 The variables whose DECL_BIT_INDEX are in the range from
58 start_current_locals (inclusive) up to num_current_locals (exclusive)
59 are declared in the "current" block. If there is a loop or branch
60 form, we set start_current_locals to num_current_locals to indicate
61 there is no current block.
62
63 The point is that if a variable in the current block is set,
64 there are no other control paths that we have to worry about.
65 Hence, we can remove it from the set of variables we are
66 checking, making its bit index available for some other variable.
67 For simplicity, we only do that if the variable's bit index
68 is (num_current_locals-1); freeing up its bit index is then
69 just a simple matter of decrementing num_current_locals.
70 The reason this is worth doing is that it is simple, and
71 allows us to use short (usually one-word) bit-strings,
72 even for methods with thousands of local variables, as
73 long as most of them are initialized immediately after or in
74 their declaration. */
4f88ccda 75static int start_current_locals = 0;
4ba9a1aa 76
4f88ccda 77static int num_current_words;
4ba9a1aa
PB
78
79static tree wfl;
80
81#define COPYN(DST, SRC, NWORDS) memcpy (DST, SRC, NWORDS * sizeof(word))
82#define COPY(DST, SRC) COPYN (DST, SRC, num_current_words)
83
84#define SET_ALL(DST) memset (DST, ~0, num_current_words * sizeof(word))
85#define CLEAR_ALL(DST) memset (DST, 0, num_current_words * sizeof(word))
86
87#define INTERSECTN(DST, SRC1, SRC2, N) \
88 do { int n = N; \
89 while (--n >= 0) DST[n] = SRC1[n] & SRC2[n]; \
90 } while (0)
91
92#define UNION(DST, SRC1, SRC2) \
93 UNIONN (DST, SRC1, SRC2, num_current_words)
94
95#define UNIONN(DST, SRC1, SRC2, N) \
96 do { int n = N; \
97 while (--n >= 0) DST[n] = SRC1[n] | SRC2[n]; \
98 } while (0)
99
100#define INTERSECT(DST, SRC1, SRC2) \
101 INTERSECTN (DST, SRC1, SRC2, num_current_words)
102
5412ef6b 103#define WORD_SIZE ((unsigned int)(sizeof(word) * BITS_PER_UNIT))
4ba9a1aa 104
d2097937
KG
105static void check_bool_init (tree, words, words, words);
106static void check_init (tree, words);
107static void check_cond_init (tree, tree, tree, words, words, words);
108static void check_bool2_init (enum tree_code, tree, tree, words, words, words);
c8e7d2e6 109struct alternatives;
d2097937
KG
110static void done_alternative (words, struct alternatives *);
111static tree get_variable_decl (tree);
112static void final_assign_error (tree);
113static void check_final_reassigned (tree, words);
4ba9a1aa 114
a92cb0c3 115#define ALLOC_WORDS(NUM) (xmalloc ((NUM) * sizeof (word)))
4ba9a1aa 116#define FREE_WORDS(PTR) (free (PTR))
4f88ccda
PB
117
118/* DECLARE_BUFFERS is used to allocate NUMBUFFER bit sets, each of
119 which is an array of length num_current_words number of words.
120 Declares a new local variable BUFFER to hold the result (or rather
121 a pointer to the first of the bit sets). In almost all cases
122 num_current_words will be 1 or at most 2, so we try to stack
123 allocate the arrays in that case, using a stack array
124 named BUFFER##_short. Each DECLARE_BUFFERS must be matched by
125 a corresponding RELEASE_BUFFERS to avoid memory leaks. */
126
127#define DECLARE_BUFFERS(BUFFER, NUMBUFFERS) \
128 word BUFFER##_short[2 * NUMBUFFERS]; \
129 words BUFFER = ALLOC_BUFFER(BUFFER##_short, NUMBUFFERS * num_current_words)
130
131#define RELEASE_BUFFERS(BUFFER) \
132 FREE_BUFFER(BUFFER, BUFFER##_short)
133
134#define ALLOC_BUFFER(SHORTBUFFER, NUMWORDS) \
135 ((NUMWORDS) * sizeof(word) <= sizeof(SHORTBUFFER) ? SHORTBUFFER \
136 : ALLOC_WORDS(NUMWORDS))
137
138#define FREE_BUFFER(BUFFER, SHORTBUFFER) \
139 if (BUFFER != SHORTBUFFER) FREE_WORDS(BUFFER)
4ba9a1aa
PB
140
141#define SET_P(WORDS, BIT) \
4f88ccda 142 (WORDS[(BIT) / WORD_SIZE] & (1 << ((BIT) % WORD_SIZE)))
4ba9a1aa
PB
143
144#define CLEAR_BIT(WORDS, BIT) \
4f88ccda 145 (WORDS[(BIT) / WORD_SIZE] &= ~ (1 << ((BIT) % WORD_SIZE)))
4ba9a1aa
PB
146
147#define SET_BIT(WORDS, BIT) \
4f88ccda 148 (WORDS[(BIT) / WORD_SIZE] |= (1 << ((BIT) % WORD_SIZE)))
4ba9a1aa
PB
149
150#define WORDS_NEEDED(BITS) (((BITS)+(WORD_SIZE-1))/(WORD_SIZE))
151
4f88ccda
PB
152#define ASSIGNED_P(WORDS, BIT) SET_P(WORDS, 2 * (BIT))
153#define UNASSIGNED_P(WORDS, BIT) SET_P(WORDS, 2 * (BIT) + 1)
154
155#define SET_ASSIGNED(WORDS, INDEX) SET_BIT (WORDS, 2 * (INDEX))
156#define SET_UNASSIGNED(WORDS, INDEX) SET_BIT (WORDS, 2 * (INDEX) + 1)
157
158#define CLEAR_ASSIGNED(WORDS, INDEX) CLEAR_BIT (WORDS, 2 * (INDEX))
159#define CLEAR_UNASSIGNED(WORDS, INDEX) CLEAR_BIT (WORDS, 2 * (INDEX) + 1)
160
161/* Get the "interesting" declaration from a MODIFY_EXPR or COMPONENT_REF.
162 Return the declaration or NULL_TREE if no interesting declaration. */
163
164static tree
0a2f0c54 165get_variable_decl (tree exp)
4f88ccda
PB
166{
167 if (TREE_CODE (exp) == VAR_DECL)
168 {
169 if (! TREE_STATIC (exp) || FIELD_FINAL (exp))
170 return exp;
171 }
172 /* We only care about final parameters. */
173 else if (TREE_CODE (exp) == PARM_DECL)
174 {
175 if (DECL_FINAL (exp))
176 return exp;
177 }
178 /* See if exp is this.field. */
179 else if (TREE_CODE (exp) == COMPONENT_REF)
180 {
181 tree op0 = TREE_OPERAND (exp, 0);
182 tree op1 = TREE_OPERAND (exp, 1);
183 tree mdecl = current_function_decl;
184 if (TREE_CODE (op0) == INDIRECT_REF
185 && TREE_CODE (op1) == FIELD_DECL
186 && ! METHOD_STATIC (mdecl)
187 && FIELD_FINAL (op1))
188 {
189 op0 = TREE_OPERAND (op0, 0);
190 if (op0 == BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)))
191 return op1;
192 }
193 }
194 return NULL_TREE;
195}
196
197static void
0a2f0c54 198final_assign_error (tree name)
4f88ccda
PB
199{
200 static const char format[]
1aca9b81 201 = "can't reassign a value to the final variable '%s'";
4f88ccda
PB
202 parse_error_context (wfl, format, IDENTIFIER_POINTER (name));
203}
204
205static void
0a2f0c54 206check_final_reassigned (tree decl, words before)
4f88ccda
PB
207{
208 int index = DECL_BIT_INDEX (decl);
209 /* A final local already assigned or a final parameter
210 assigned must be reported as errors */
211 if (DECL_FINAL (decl) && index != -2
212 && (index < loop_current_locals /* I.e. -1, or outside current loop. */
213 || ! UNASSIGNED_P (before, index)))
214 {
215 final_assign_error (DECL_NAME (decl));
216 }
217}
218
4ba9a1aa 219/* Check a conditional form (TEST_EXP ? THEN_EXP : ELSE_EXP) for
4f88ccda 220 definite [un]assignment.
4ba9a1aa
PB
221 BEFORE, WHEN_FALSE, and WHEN_TRUE are as in check_bool_init. */
222
4bcde32e 223static void
0a2f0c54
KG
224check_cond_init (tree test_exp, tree then_exp, tree else_exp,
225 words before, words when_false, words when_true)
4ba9a1aa 226{
4f88ccda
PB
227 int save_start_current_locals = start_current_locals;
228 DECLARE_BUFFERS(test_false, 6);
229 words test_true = test_false + num_current_words;
230 words then_false = test_true + num_current_words;
231 words then_true = then_false + num_current_words;
232 words else_false = then_true + num_current_words;
233 words else_true = else_false + num_current_words;
234 start_current_locals = num_current_locals;
235
4ba9a1aa
PB
236 check_bool_init (test_exp, before, test_false, test_true);
237 check_bool_init (then_exp, test_true, then_false, then_true);
238 check_bool_init (else_exp, test_false, else_false, else_true);
239 INTERSECT (when_false, then_false, else_false);
240 INTERSECT (when_true, then_true, else_true);
4f88ccda
PB
241 RELEASE_BUFFERS(test_false);
242 start_current_locals = save_start_current_locals;
4ba9a1aa
PB
243}
244
245/* Check a boolean binary form CODE (EXP0, EXP1),
01f76283 246 where CODE is one of EQ_EXPR, BIT_AND_EXPR, or BIT_IOR_EXPR.
4ba9a1aa
PB
247 BEFORE, WHEN_FALSE, and WHEN_TRUE are as in check_bool_init. */
248
249static void
0a2f0c54
KG
250check_bool2_init (enum tree_code code, tree exp0, tree exp1,
251 words before, words when_false, words when_true)
4ba9a1aa 252{
4f88ccda
PB
253 word buf[2*4];
254 words tmp = num_current_words <= 2 ? buf
4ba9a1aa
PB
255 : ALLOC_WORDS (4 * num_current_words);
256 words when_false_0 = tmp;
257 words when_false_1 = tmp+num_current_words;
258 words when_true_0 = tmp+2*num_current_words;
259 words when_true_1 = tmp+3*num_current_words;
260 check_bool_init (exp0, before, when_false_0, when_true_0);
261 INTERSECT (before, when_false_0, when_true_0);
262 check_bool_init (exp1, before, when_false_1, when_true_1);
263
264 INTERSECT (before, when_false_1, when_true_1);
265
266 if (code == EQ_EXPR)
267 {
268 /* Now set:
269 * when_true = (when_false_1 INTERSECTION when_true_1)
270 * UNION (when_true_0 INTERSECTION when_false_1)
271 * UNION (when_false_0 INTERSECTION when_true_1);
272 * using when_false and before as temporary working areas. */
273 INTERSECT (when_true, when_true_0, when_false_1);
274 INTERSECT (when_false, when_true_0, when_false_1);
275 UNION (when_true, when_true, when_false);
276 UNION (when_true, when_true, before);
277
278 /* Now set:
279 * when_false = (when_false_1 INTERSECTION when_true_1)
280 * UNION (when_true_0 INTERSECTION when_true_1)
281 * UNION (when_false_0 INTERSECTION when_false_1);
282 * using before as a temporary working area. */
283 INTERSECT (when_false, when_true_0, when_true_1);
284 UNION (when_false, when_false, before);
285 INTERSECT (before, when_false_0, when_false_1);
286 UNION (when_false, when_false, before);
287 }
f2693f2f 288 else if (code == BIT_AND_EXPR || code == TRUTH_AND_EXPR)
4ba9a1aa
PB
289 {
290 UNION (when_true, when_true_0, when_true_1);
291 INTERSECT (when_false, when_false_0, when_false_1);
01f76283 292 UNION (when_false, when_false, before);
4ba9a1aa 293 }
f2693f2f 294 else /* if (code == BIT_IOR_EXPR || code == TRUTH_OR_EXPR) */
4ba9a1aa
PB
295 {
296 UNION (when_false, when_false_0, when_false_1);
297 INTERSECT (when_true, when_true_0, when_true_1);
01f76283 298 UNION (when_true, when_true, before);
4ba9a1aa
PB
299 }
300
301 if (tmp != buf)
302 FREE_WORDS (tmp);
303}
304
4f88ccda
PB
305/* Check a boolean expression EXP for definite [un]assignment.
306 BEFORE is the set of variables definitely [un]assigned before the
307 conditional. (This bitstring may be modified arbitrarily in this function.)
308 On output, WHEN_FALSE is the set of variables [un]definitely assigned after
4ba9a1aa 309 the conditional when the conditional is false.
4f88ccda 310 On output, WHEN_TRUE is the set of variables definitely [un]assigned after
4ba9a1aa 311 the conditional when the conditional is true.
f6e8b583 312 (WHEN_FALSE and WHEN_TRUE are overwritten with initial values ignored.)
4ba9a1aa
PB
313 (None of BEFORE, WHEN_FALSE, or WHEN_TRUE can overlap, as they may
314 be used as temporary working areas. */
4ba9a1aa
PB
315
316static void
0a2f0c54 317check_bool_init (tree exp, words before, words when_false, words when_true)
4ba9a1aa
PB
318{
319 switch (TREE_CODE (exp))
320 {
321 case COND_EXPR:
322 check_cond_init (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
323 TREE_OPERAND (exp, 2),
324 before, when_false, when_true);
325 return;
326
327 case TRUTH_ANDIF_EXPR:
328 check_cond_init (TREE_OPERAND (exp, 0),
329 TREE_OPERAND (exp, 1), boolean_false_node,
330 before, when_false, when_true);
331 return;
332 case TRUTH_ORIF_EXPR:
333 check_cond_init (TREE_OPERAND (exp, 0),
334 boolean_true_node, TREE_OPERAND (exp, 1),
335 before, when_false, when_true);
336 return;
337 case TRUTH_NOT_EXPR:
338 check_bool_init (TREE_OPERAND (exp, 0), before, when_true, when_false);
339 return;
340 case MODIFY_EXPR:
341 {
342 tree tmp = TREE_OPERAND (exp, 0);
4f88ccda 343 if ((tmp = get_variable_decl (tmp)) != NULL_TREE)
4ba9a1aa
PB
344 {
345 int index;
346 check_bool_init (TREE_OPERAND (exp, 1), before,
347 when_false, when_true);
4f88ccda 348 check_final_reassigned (tmp, before);
4ba9a1aa
PB
349 index = DECL_BIT_INDEX (tmp);
350 if (index >= 0)
351 {
4f88ccda
PB
352 SET_ASSIGNED (when_false, index);
353 SET_ASSIGNED (when_true, index);
354 CLEAR_UNASSIGNED (when_false, index);
355 CLEAR_UNASSIGNED (when_true, index);
4ba9a1aa
PB
356 }
357 break;
358 }
359 }
360 goto do_default;
361
362 case BIT_AND_EXPR:
01f76283 363 case BIT_IOR_EXPR:
f2693f2f
PB
364 case TRUTH_AND_EXPR:
365 case TRUTH_OR_EXPR:
4ba9a1aa
PB
366 case EQ_EXPR:
367 check_bool2_init (TREE_CODE (exp),
368 TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
369 before, when_false, when_true);
370 return;
371
f2693f2f 372 case TRUTH_XOR_EXPR:
4ba9a1aa
PB
373 case BIT_XOR_EXPR:
374 case NE_EXPR:
375 /* Just like EQ_EXPR, but switch when_true and when_false. */
376 check_bool2_init (EQ_EXPR, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
377 before, when_true, when_false);
378
379 return;
380
381 case INTEGER_CST:
382 if (integer_zerop (exp))
383 {
384 SET_ALL (when_true);
385 COPY (when_false, before);
386 }
387 else
388 {
389 SET_ALL (when_false);
390 COPY (when_true, before);
391 }
392 break;
393 default:
394 do_default:
395 check_init (exp, before);
396 COPY (when_false, before);
397 COPY (when_true, before);
398 }
399}
400
401/* Used to keep track of control flow branches. */
402
403struct alternatives
404{
405 struct alternatives *outer;
406
407 /* The value of num_current_locals at the start of this compound. */
408 int num_locals;
409
634661fe 410 /* The value of the "before" set at the start of the control structure.
4ba9a1aa
PB
411 Used for SWITCH_EXPR but not set for LABELED_BLOCK_EXPR. */
412 words saved;
413
414 int save_start_current_locals;
415
416 /* If num_current_words==1, combined==&one_word, for efficiency. */
417 word one_word;
418
419 /* The intersection of the "after" sets from previous branches. */
420 words combined;
421
422 tree block;
423};
424
425struct alternatives * alternatives = NULL;
426
4f88ccda
PB
427/* Begin handling a control flow branch.
428 BEFORE is the state of [un]assigned variables on entry.
429 CURRENT is a struct alt to manage the branch alternatives. */
430
4ba9a1aa
PB
431#define BEGIN_ALTERNATIVES(before, current) \
432{ \
433 current.saved = NULL; \
434 current.num_locals = num_current_locals; \
435 current.combined = num_current_words <= 1 ? &current.one_word \
436 : ALLOC_WORDS (num_current_words); \
437 SET_ALL (current.combined); \
438 current.outer = alternatives; \
439 alternatives = &current; \
440 current.save_start_current_locals = start_current_locals; \
441 start_current_locals = num_current_locals; \
442}
443
4f88ccda
PB
444/* We have finished with one branch of branching control flow.
445 Store the [un]assigned state, merging (intersecting) it with the state
446 of previous alternative branches. */
447
4ba9a1aa 448static void
0a2f0c54 449done_alternative (words after, struct alternatives *current)
4ba9a1aa
PB
450{
451 INTERSECTN (current->combined, current->combined, after,
4f88ccda 452 WORDS_NEEDED (2 * current->num_locals));
4ba9a1aa
PB
453}
454
4f88ccda
PB
455/* Used when we done with a control flow branch and are all merged again.
456 * AFTER is the merged state of [un]assigned variables,
457 CURRENT is a struct alt that was passed to BEGIN_ALTERNATIVES. */
458
4ba9a1aa
PB
459#define END_ALTERNATIVES(after, current) \
460{ \
461 alternatives = current.outer; \
462 COPY (after, current.combined); \
463 if (current.combined != &current.one_word) \
464 FREE_WORDS (current.combined); \
465 start_current_locals = current.save_start_current_locals; \
466}
467
c7303e41 468/* Check for (un)initialized local variables in EXP. */
4ba9a1aa
PB
469
470static void
0a2f0c54 471check_init (tree exp, words before)
4ba9a1aa
PB
472{
473 tree tmp;
474 again:
475 switch (TREE_CODE (exp))
476 {
477 case VAR_DECL:
4f88ccda
PB
478 case PARM_DECL:
479 if (! FIELD_STATIC (exp) && DECL_NAME (exp) != NULL_TREE
480 && DECL_NAME (exp) != this_identifier_node)
4ba9a1aa
PB
481 {
482 int index = DECL_BIT_INDEX (exp);
4f88ccda
PB
483 /* We don't want to report and mark as non initialized class
484 initialization flags. */
485 if (! LOCAL_CLASS_INITIALIZATION_FLAG_P (exp)
486 && index >= 0 && ! ASSIGNED_P (before, index))
4ba9a1aa 487 {
c2952b01
APB
488 parse_error_context
489 (wfl, "Variable `%s' may not have been initialized",
490 IDENTIFIER_POINTER (DECL_NAME (exp)));
4ba9a1aa 491 /* Suppress further errors. */
4f88ccda 492 DECL_BIT_INDEX (exp) = -2;
4ba9a1aa
PB
493 }
494 }
495 break;
4f88ccda
PB
496
497 case COMPONENT_REF:
498 check_init (TREE_OPERAND (exp, 0), before);
499 if ((tmp = get_variable_decl (exp)) != NULL_TREE)
500 {
501 int index = DECL_BIT_INDEX (tmp);
502 if (index >= 0 && ! ASSIGNED_P (before, index))
503 {
504 parse_error_context
505 (wfl, "variable '%s' may not have been initialized",
506 IDENTIFIER_POINTER (DECL_NAME (tmp)));
507 /* Suppress further errors. */
508 DECL_BIT_INDEX (tmp) = -2;
509 }
510 }
511 break;
512
4ba9a1aa
PB
513 case MODIFY_EXPR:
514 tmp = TREE_OPERAND (exp, 0);
c2952b01
APB
515 /* We're interested in variable declaration and parameter
516 declaration when they're declared with the `final' modifier. */
4f88ccda 517 if ((tmp = get_variable_decl (tmp)) != NULL_TREE)
4ba9a1aa
PB
518 {
519 int index;
520 check_init (TREE_OPERAND (exp, 1), before);
4f88ccda 521 check_final_reassigned (tmp, before);
4ba9a1aa
PB
522 index = DECL_BIT_INDEX (tmp);
523 if (index >= 0)
4f88ccda
PB
524 {
525 SET_ASSIGNED (before, index);
526 CLEAR_UNASSIGNED (before, index);
527 }
4009bb7d
APB
528 /* Minor optimization. See comment for start_current_locals.
529 If we're optimizing for class initialization, we keep
530 this information to check whether the variable is
531 definitely assigned when once we checked the whole
532 function. */
4f88ccda 533 if (! STATIC_CLASS_INIT_OPT_P () /* FIXME */
4009bb7d 534 && index >= start_current_locals
4ba9a1aa
PB
535 && index == num_current_locals - 1)
536 {
537 num_current_locals--;
538 DECL_BIT_INDEX (tmp) = -1;
539 }
540 break;
541 }
4f88ccda
PB
542 else if (TREE_CODE (tmp = TREE_OPERAND (exp, 0)) == COMPONENT_REF)
543 {
544 tree decl;
545 check_init (tmp, before);
546 check_init (TREE_OPERAND (exp, 1), before);
547 decl = TREE_OPERAND (tmp, 1);
548 if (DECL_FINAL (decl))
549 final_assign_error (DECL_NAME (decl));
550 break;
551 }
022dcc46 552 else if (TREE_CODE (tmp) == COMPONENT_REF && IS_ARRAY_LENGTH_ACCESS (tmp))
4f88ccda
PB
553 {
554 /* We can't emit a more specific message here, because when
555 compiling to bytecodes we don't get here. */
556 final_assign_error (length_identifier_node);
557 }
4ba9a1aa
PB
558 else
559 goto binop;
560 case BLOCK:
561 if (BLOCK_EXPR_BODY (exp))
562 {
563 tree decl = BLOCK_EXPR_DECLS (exp);
564 int words_needed;
565 word* tmp;
566 int i;
567 int save_start_current_locals = start_current_locals;
568 int save_num_current_words = num_current_words;
569 start_current_locals = num_current_locals;
570 for (; decl != NULL_TREE; decl = TREE_CHAIN (decl))
571 {
572 DECL_BIT_INDEX (decl) = num_current_locals++;
573 }
4f88ccda 574 words_needed = WORDS_NEEDED (2 * num_current_locals);
4ba9a1aa
PB
575 if (words_needed > num_current_words)
576 {
577 tmp = ALLOC_WORDS (words_needed);
578 COPY (tmp, before);
579 num_current_words = words_needed;
580 }
581 else
582 tmp = before;
583 for (i = start_current_locals; i < num_current_locals; i++)
4f88ccda
PB
584 {
585 CLEAR_ASSIGNED (tmp, i);
586 SET_UNASSIGNED (tmp, i);
587 }
4ba9a1aa 588 check_init (BLOCK_EXPR_BODY (exp), tmp);
5412ef6b
PB
589
590 /* Re-set DECL_BIT_INDEX since it is also DECL_POINTER_ALIAS_SET. */
591 for (decl = BLOCK_EXPR_DECLS (exp);
592 decl != NULL_TREE; decl = TREE_CHAIN (decl))
593 {
594 if (LOCAL_CLASS_INITIALIZATION_FLAG_P (decl))
595 {
596 int index = DECL_BIT_INDEX (decl);
597 tree fndecl = DECL_CONTEXT (decl);
598 if (fndecl && METHOD_STATIC (fndecl)
599 && (DECL_INITIAL (decl) == boolean_true_node
600 || (index >= 0 && ASSIGNED_P (tmp, index))))
e2500fed
GK
601 *(htab_find_slot
602 (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
603 DECL_FUNCTION_INIT_TEST_CLASS (decl), INSERT)) =
604 DECL_FUNCTION_INIT_TEST_CLASS (decl);
5412ef6b
PB
605 }
606 DECL_BIT_INDEX (decl) = -1;
607 }
608
4ba9a1aa
PB
609 num_current_locals = start_current_locals;
610 start_current_locals = save_start_current_locals;
611 if (tmp != before)
612 {
613 num_current_words = save_num_current_words;
614 COPY (before, tmp);
615 FREE_WORDS (tmp);
616 }
617 }
618 break;
619 case LOOP_EXPR:
620 {
4f88ccda
PB
621 /* The JLS 2nd edition discusses a complication determining
622 definite unassignment of loop statements. They define a
623 "hypothetical" analysis model. We do something much
624 simpler: We just disallow assignments inside loops to final
625 variables declared outside the loop. This means we may
626 disallow some contrived assignments that the JLS, but I
627 can't see how anything except a very contrived testcase (a
628 do-while whose condition is false?) would care. */
629
4ba9a1aa 630 struct alternatives alt;
4f88ccda
PB
631 int save_loop_current_locals = loop_current_locals;
632 int save_start_current_locals = start_current_locals;
633 loop_current_locals = num_current_locals;
634 start_current_locals = num_current_locals;
4ba9a1aa
PB
635 BEGIN_ALTERNATIVES (before, alt);
636 alt.block = exp;
637 check_init (TREE_OPERAND (exp, 0), before);
4ba9a1aa 638 END_ALTERNATIVES (before, alt);
4f88ccda
PB
639 loop_current_locals = save_loop_current_locals;
640 start_current_locals = save_start_current_locals;
4ba9a1aa
PB
641 return;
642 }
643 case EXIT_EXPR:
644 {
645 struct alternatives *alt = alternatives;
4f88ccda
PB
646 DECLARE_BUFFERS(when_true, 2);
647 words when_false = when_true + num_current_words;
9a7ab4b3 648#ifdef ENABLE_JC1_CHECKING
4ba9a1aa 649 if (TREE_CODE (alt->block) != LOOP_EXPR)
400500c4 650 abort ();
4ba9a1aa
PB
651#endif
652 check_bool_init (TREE_OPERAND (exp, 0), before, when_false, when_true);
653 done_alternative (when_true, alt);
654 COPY (before, when_false);
4f88ccda 655 RELEASE_BUFFERS(when_true);
4ba9a1aa
PB
656 return;
657 }
658 case LABELED_BLOCK_EXPR:
659 {
660 struct alternatives alt;
661 BEGIN_ALTERNATIVES (before, alt);
662 alt.block = exp;
af8b342a
APB
663 if (LABELED_BLOCK_BODY (exp))
664 check_init (LABELED_BLOCK_BODY (exp), before);
4ba9a1aa
PB
665 done_alternative (before, &alt);
666 END_ALTERNATIVES (before, alt);
667 return;
668 }
669 case EXIT_BLOCK_EXPR:
670 {
671 tree block = TREE_OPERAND (exp, 0);
672 struct alternatives *alt = alternatives;
673 while (alt->block != block)
674 alt = alt->outer;
675 done_alternative (before, alt);
676 SET_ALL (before);
677 return;
678 }
679 case SWITCH_EXPR:
680 {
681 struct alternatives alt;
4f88ccda 682 word buf[2];
4ba9a1aa
PB
683 check_init (TREE_OPERAND (exp, 0), before);
684 BEGIN_ALTERNATIVES (before, alt);
4f88ccda 685 alt.saved = ALLOC_BUFFER(buf, num_current_words);
4ba9a1aa
PB
686 COPY (alt.saved, before);
687 alt.block = exp;
688 check_init (TREE_OPERAND (exp, 1), before);
689 done_alternative (before, &alt);
3afdfae8
TT
690 if (! SWITCH_HAS_DEFAULT (exp))
691 done_alternative (alt.saved, &alt);
4f88ccda 692 FREE_BUFFER(alt.saved, buf);
4ba9a1aa
PB
693 END_ALTERNATIVES (before, alt);
694 return;
695 }
a5cb134d 696 case CASE_EXPR:
3afdfae8 697 case DEFAULT_EXPR:
4ba9a1aa
PB
698 {
699 int i;
700 struct alternatives *alt = alternatives;
701 while (TREE_CODE (alt->block) != SWITCH_EXPR)
702 alt = alt->outer;
4f88ccda 703 COPYN (before, alt->saved, WORDS_NEEDED (2 * alt->num_locals));
4ba9a1aa 704 for (i = alt->num_locals; i < num_current_locals; i++)
4f88ccda 705 CLEAR_ASSIGNED (before, i);
4ba9a1aa
PB
706 break;
707 }
708
4ba9a1aa
PB
709 case TRY_EXPR:
710 {
711 tree try_clause = TREE_OPERAND (exp, 0);
712 tree clause = TREE_OPERAND (exp, 1);
4f88ccda
PB
713 word buf[2*2];
714 words tmp = (num_current_words <= 2 ? buf
715 : ALLOC_WORDS (2 * num_current_words));
716 words save = tmp + num_current_words;
4ba9a1aa
PB
717 struct alternatives alt;
718 BEGIN_ALTERNATIVES (before, alt);
719 COPY (save, before);
720 COPY (tmp, save);
721 check_init (try_clause, tmp);
722 done_alternative (tmp, &alt);
723 for ( ; clause != NULL_TREE; clause = TREE_CHAIN (clause))
724 {
725 tree catch_clause = TREE_OPERAND (clause, 0);
726 COPY (tmp, save);
727 check_init (catch_clause, tmp);
728 done_alternative (tmp, &alt);
729 }
4f88ccda
PB
730 if (tmp != buf)
731 {
732 FREE_WORDS (tmp);
733 }
4ba9a1aa
PB
734 END_ALTERNATIVES (before, alt);
735 }
736 return;
737
0a3af4d8
PB
738 case TRY_FINALLY_EXPR:
739 {
4f88ccda 740 DECLARE_BUFFERS(tmp, 1);
0a3af4d8 741 COPY (tmp, before);
4a83be51
PB
742 check_init (TREE_OPERAND (exp, 0), before);
743 check_init (TREE_OPERAND (exp, 1), tmp);
744 UNION (before, before, tmp);
4f88ccda 745 RELEASE_BUFFERS(tmp);
0a3af4d8
PB
746 }
747 return;
748
4ba9a1aa
PB
749 case RETURN_EXPR:
750 case THROW_EXPR:
751 if (TREE_OPERAND (exp, 0))
752 check_init (TREE_OPERAND (exp, 0), before);
b82daa87 753 goto never_continues;
4ba9a1aa
PB
754
755 case ERROR_MARK:
b82daa87 756 never_continues:
4ba9a1aa 757 SET_ALL (before);
b82daa87 758 return;
4ba9a1aa
PB
759
760 case COND_EXPR:
761 case TRUTH_ANDIF_EXPR:
762 case TRUTH_ORIF_EXPR:
763 {
4f88ccda
PB
764 DECLARE_BUFFERS(when_true, 2);
765 words when_false = when_true + num_current_words;
4ba9a1aa
PB
766 check_bool_init (exp, before, when_false, when_true);
767 INTERSECT (before, when_false, when_true);
4f88ccda 768 RELEASE_BUFFERS(when_true);
4ba9a1aa
PB
769 }
770 break;
4f88ccda
PB
771
772 case NOP_EXPR:
6de9cd9a 773 if (IS_EMPTY_STMT (exp))
4f88ccda
PB
774 break;
775 /* ... else fall through ... */
4ba9a1aa
PB
776 case UNARY_PLUS_EXPR:
777 case NEGATE_EXPR:
f2693f2f
PB
778 case TRUTH_AND_EXPR:
779 case TRUTH_OR_EXPR:
780 case TRUTH_XOR_EXPR:
4ba9a1aa
PB
781 case TRUTH_NOT_EXPR:
782 case BIT_NOT_EXPR:
783 case CONVERT_EXPR:
458530ee 784 case BIT_FIELD_REF:
4ba9a1aa
PB
785 case FLOAT_EXPR:
786 case FIX_TRUNC_EXPR:
787 case INDIRECT_REF:
788 case ADDR_EXPR:
4ba9a1aa
PB
789 case NON_LVALUE_EXPR:
790 case INSTANCEOF_EXPR:
d77a712d
AH
791 case FIX_CEIL_EXPR:
792 case FIX_FLOOR_EXPR:
793 case FIX_ROUND_EXPR:
d77a712d 794 case ABS_EXPR:
4ba9a1aa
PB
795 /* Avoid needless recursion. */
796 exp = TREE_OPERAND (exp, 0);
797 goto again;
798
1aca9b81
TT
799 case PREDECREMENT_EXPR:
800 case PREINCREMENT_EXPR:
801 case POSTDECREMENT_EXPR:
802 case POSTINCREMENT_EXPR:
803 tmp = get_variable_decl (TREE_OPERAND (exp, 0));
804 if (tmp != NULL_TREE && DECL_FINAL (tmp))
805 final_assign_error (DECL_NAME (tmp));
806
807 /* Avoid needless recursion. */
808 exp = TREE_OPERAND (exp, 0);
809 goto again;
810
1729c265
APB
811 case SAVE_EXPR:
812 if (IS_INIT_CHECKED (exp))
813 return;
814 IS_INIT_CHECKED (exp) = 1;
815 exp = TREE_OPERAND (exp, 0);
816 goto again;
817
4ba9a1aa
PB
818 case COMPOUND_EXPR:
819 case PLUS_EXPR:
820 case MINUS_EXPR:
821 case MULT_EXPR:
822 case TRUNC_DIV_EXPR:
823 case TRUNC_MOD_EXPR:
824 case RDIV_EXPR:
825 case LSHIFT_EXPR:
826 case RSHIFT_EXPR:
827 case URSHIFT_EXPR:
828 case BIT_AND_EXPR:
829 case BIT_XOR_EXPR:
830 case BIT_IOR_EXPR:
831 case EQ_EXPR:
832 case NE_EXPR:
833 case GT_EXPR:
834 case GE_EXPR:
835 case LT_EXPR:
836 case LE_EXPR:
1a6d4fb7 837 case MAX_EXPR:
ac1d97ce 838 case MIN_EXPR:
4ba9a1aa 839 case ARRAY_REF:
d77a712d
AH
840 case LROTATE_EXPR:
841 case RROTATE_EXPR:
842 case CEIL_DIV_EXPR:
843 case FLOOR_DIV_EXPR:
844 case ROUND_DIV_EXPR:
845 case CEIL_MOD_EXPR:
846 case FLOOR_MOD_EXPR:
847 case ROUND_MOD_EXPR:
848 case EXACT_DIV_EXPR:
4ba9a1aa
PB
849 binop:
850 check_init (TREE_OPERAND (exp, 0), before);
851 /* Avoid needless recursion, especially for COMPOUND_EXPR. */
852 exp = TREE_OPERAND (exp, 1);
853 goto again;
854
4ba9a1aa
PB
855 case RESULT_DECL:
856 case FUNCTION_DECL:
857 case INTEGER_CST:
858 case REAL_CST:
859 case STRING_CST:
f17f1898 860 case JAVA_EXC_OBJ_EXPR:
4ba9a1aa
PB
861 break;
862
863 case NEW_CLASS_EXPR:
864 case CALL_EXPR:
865 {
b82daa87 866 tree func = TREE_OPERAND (exp, 0);
4ba9a1aa 867 tree x = TREE_OPERAND (exp, 1);
b82daa87
PB
868 if (TREE_CODE (func) == ADDR_EXPR)
869 func = TREE_OPERAND (func, 0);
870 check_init (func, before);
871
4ba9a1aa
PB
872 for ( ; x != NULL_TREE; x = TREE_CHAIN (x))
873 check_init (TREE_VALUE (x), before);
ce1c98ea 874 if (func == throw_node)
b82daa87 875 goto never_continues;
4ba9a1aa
PB
876 }
877 break;
878
879 case NEW_ARRAY_INIT:
880 {
881 tree x = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
882 for ( ; x != NULL_TREE; x = TREE_CHAIN (x))
883 check_init (TREE_VALUE (x), before);
884 }
885 break;
886
887 case EXPR_WITH_FILE_LOCATION:
888 {
436fac17 889 location_t saved_location = input_location;
4ba9a1aa
PB
890 tree saved_wfl = wfl;
891 tree body = EXPR_WFL_NODE (exp);
6de9cd9a 892 if (IS_EMPTY_STMT (body))
4ba9a1aa
PB
893 break;
894 wfl = exp;
895 input_filename = EXPR_WFL_FILENAME (exp);
d479d37f 896 input_line = EXPR_WFL_LINENO (exp);
4ba9a1aa 897 check_init (body, before);
436fac17 898 input_location = saved_location;
4ba9a1aa
PB
899 wfl = saved_wfl;
900 }
901 break;
902
903 default:
400500c4
RK
904 internal_error
905 ("internal error in check-init: tree code not implemented: %s",
906 tree_code_name [(int) TREE_CODE (exp)]);
4ba9a1aa
PB
907 }
908}
909
4f88ccda 910void
0a2f0c54 911check_for_initialization (tree body, tree mdecl)
4ba9a1aa 912{
4f88ccda
PB
913 tree decl;
914 word buf[2];
915 words before = buf;
916 tree owner = DECL_CONTEXT (mdecl);
917 int is_static_method = METHOD_STATIC (mdecl);
918 /* We don't need to check final fields of <init> it it calls this(). */
919 int is_finit_method = DECL_FINIT_P (mdecl) || DECL_INSTINIT_P (mdecl);
920 int is_init_method
921 = (is_finit_method || DECL_CLINIT_P (mdecl)
922 || (DECL_INIT_P (mdecl) && ! DECL_INIT_CALLS_THIS (mdecl)));
923
924 start_current_locals = num_current_locals = 0;
925 num_current_words = 2;
926
927 if (is_init_method)
928 {
929 int words_needed, i;
930 for (decl = TYPE_FIELDS (owner);
931 decl != NULL_TREE; decl = TREE_CHAIN (decl))
932 {
933 if (DECL_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
934 {
935 if (DECL_FIELD_FINAL_IUD (decl))
936 DECL_BIT_INDEX (decl) = -1;
937 else
938 DECL_BIT_INDEX (decl) = num_current_locals++;
939 }
940 }
941 words_needed = WORDS_NEEDED (2 * num_current_locals);
942 if (words_needed > 2)
943 {
944 num_current_words = words_needed;
945 before = ALLOC_WORDS(words_needed);
946 }
947 i = 0;
948 for (decl = TYPE_FIELDS (owner);
949 decl != NULL_TREE; decl = TREE_CHAIN (decl))
950 {
951 if (FIELD_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
952 {
953 if (! DECL_FIELD_FINAL_IUD (decl))
954 {
955 CLEAR_ASSIGNED (before, i);
956 SET_UNASSIGNED (before, i);
957 i++;
958 }
959 }
960 }
961
962 }
963
964 check_init (body, before);
965
966 if (is_init_method)
967 {
968 for (decl = TYPE_FIELDS (owner);
969 decl != NULL_TREE; decl = TREE_CHAIN (decl))
970 {
971 if (FIELD_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
972 {
973 int index = DECL_BIT_INDEX (decl);
974 if (index >= 0 && ! ASSIGNED_P (before, index))
975 {
976 if (! is_finit_method)
ddd2d57e
RH
977 error ("%Jfinal field '%D' may not have been initialized",
978 decl, decl);
4f88ccda
PB
979 }
980 else if (is_finit_method)
981 DECL_FIELD_FINAL_IUD (decl) = 1;
982
983 /* Re-set to initial state, since we later may use the
984 same bit for DECL_POINTER_ALIAS_SET. */
985 DECL_BIT_INDEX (decl) = -1;
986 }
987 }
988 }
989
990 start_current_locals = num_current_locals = 0;
4009bb7d 991}