]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/java/check-init.c
IA-64 ABI Exception Handling.
[thirdparty/gcc.git] / gcc / java / check-init.c
1 /* Code to test for "definitive assignment".
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU CC; see the file COPYING. If not, write to
16 the Free Software Foundation, 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18
19 Java and all Java-based marks are trademarks or registered trademarks
20 of Sun Microsystems, Inc. in the United States and other countries.
21 The Free Software Foundation is independent of Sun Microsystems, Inc. */
22
23 /* Written by Per Bothner <bothner@cygnus.com>, January 1999. */
24
25 #include "config.h"
26 #include "system.h"
27 #include "tree.h"
28 #include "java-tree.h"
29 #include "toplev.h" /* Needed for fatal. */
30
31 /* The basic idea is that we assign each local variable declaration
32 an index, and then we pass around bitstrings, where the i'th bit
33 is set if decl whose DECL_BIT_INDEX is i is definitely assigned. */
34
35 /* One segment of a bitstring. */
36 typedef unsigned int word;
37
38 /* Pointer to a bitstring. */
39 typedef word *words;
40
41 /* Number of locals variables currently active. */
42 int num_current_locals = 0;
43
44 /* The index of the first local variable in the current block.
45
46 The variables whose DECL_BIT_INDEX are in the range from
47 start_current_locals (inclusive) up to num_current_locals (exclusive)
48 are declared in the "current" block. If there is a loop or branch
49 form, we set start_current_locals to num_current_locals to indicate
50 there is no current block.
51
52 The point is that if a variable in the current block is set,
53 there are no other control paths that we have to worry about.
54 Hence, we can remove it from the set of variables we are
55 checking, making its bit index available for some other variable.
56 For simplicity, we only do that if the variable's bit index
57 is (num_current_locals-1); freeing up its bit index is then
58 just a simple matter of decrementing num_current_locals.
59 The reason this is worth doing is that it is simple, and
60 allows us to use short (usually one-word) bit-strings,
61 even for methods with thousands of local variables, as
62 long as most of them are initialized immediately after or in
63 their declaration. */
64 int start_current_locals = 0;
65
66 int num_current_words = 1;
67
68 static tree wfl;
69
70 #define COPYN(DST, SRC, NWORDS) memcpy (DST, SRC, NWORDS * sizeof(word))
71 #define COPY(DST, SRC) COPYN (DST, SRC, num_current_words)
72
73 #define SET_ALL(DST) memset (DST, ~0, num_current_words * sizeof(word))
74 #define CLEAR_ALL(DST) memset (DST, 0, num_current_words * sizeof(word))
75
76 #define INTERSECTN(DST, SRC1, SRC2, N) \
77 do { int n = N; \
78 while (--n >= 0) DST[n] = SRC1[n] & SRC2[n]; \
79 } while (0)
80
81 #define UNION(DST, SRC1, SRC2) \
82 UNIONN (DST, SRC1, SRC2, num_current_words)
83
84 #define UNIONN(DST, SRC1, SRC2, N) \
85 do { int n = N; \
86 while (--n >= 0) DST[n] = SRC1[n] | SRC2[n]; \
87 } while (0)
88
89 #define INTERSECT(DST, SRC1, SRC2) \
90 INTERSECTN (DST, SRC1, SRC2, num_current_words)
91
92 #define WORD_SIZE ((unsigned int)(sizeof(word) * 8))
93
94 static void check_bool_init PARAMS ((tree, words, words, words));
95 static void check_init PARAMS ((tree, words));
96 static void check_cond_init PARAMS ((tree, tree, tree, words, words, words));
97 static void check_bool2_init PARAMS ((enum tree_code, tree, tree, words, words, words));
98 struct alternatives;
99 static void done_alternative PARAMS ((words, struct alternatives *));
100
101 #if 0
102 #define ALLOC_WORDS(NUM) ((word*) xmalloc ((NUM) * sizeof (word)))
103 #define FREE_WORDS(PTR) (free (PTR))
104 #else
105 #define ALLOC_WORDS(NUM) ((word*)alloca ((NUM) * sizeof (word)))
106 #define FREE_WORDS(PTR) ((void)0)
107 #endif
108
109 #define SET_P(WORDS, BIT) \
110 (WORDS[BIT / WORD_SIZE] & (1 << (BIT % WORD_SIZE)))
111
112 #define CLEAR_BIT(WORDS, BIT) \
113 (WORDS[BIT / WORD_SIZE] &= ~ (1 << (BIT % WORD_SIZE)))
114
115 #define SET_BIT(WORDS, BIT) \
116 (WORDS[BIT / WORD_SIZE] |= (1 << (BIT % WORD_SIZE)))
117
118 #define WORDS_NEEDED(BITS) (((BITS)+(WORD_SIZE-1))/(WORD_SIZE))
119
120 /* Check a conditional form (TEST_EXP ? THEN_EXP : ELSE_EXP) for
121 definite assignment.
122 BEFORE, WHEN_FALSE, and WHEN_TRUE are as in check_bool_init. */
123
124 static void
125 check_cond_init (test_exp, then_exp, else_exp,
126 before, when_false, when_true)
127 tree test_exp, then_exp, else_exp;
128 words before, when_false, when_true;
129 {
130 words tmp = ALLOC_WORDS (6 * num_current_words);
131 words test_false = tmp;
132 words test_true = tmp + num_current_words;
133 words then_false = tmp + 2 * num_current_words;
134 words then_true = tmp + 3 * num_current_words;
135 words else_false = tmp + 4 * num_current_words;
136 words else_true = tmp + 5 * num_current_words;
137 check_bool_init (test_exp, before, test_false, test_true);
138 check_bool_init (then_exp, test_true, then_false, then_true);
139 check_bool_init (else_exp, test_false, else_false, else_true);
140 INTERSECT (when_false, then_false, else_false);
141 INTERSECT (when_true, then_true, else_true);
142 FREE_WORDS (tmp);
143 }
144
145 /* Check a boolean binary form CODE (EXP0, EXP1),
146 where CODE is one of EQ_EXPR, BIT_AND_EXPR, or BIT_IOR_EXPR.
147 BEFORE, WHEN_FALSE, and WHEN_TRUE are as in check_bool_init. */
148
149 static void
150 check_bool2_init (code, exp0, exp1, before, when_false, when_true)
151 enum tree_code code; tree exp0, exp1;
152 words before, when_false, when_true;
153 {
154 word buf[4];
155 words tmp = num_current_words <= 1 ? buf
156 : ALLOC_WORDS (4 * num_current_words);
157 words when_false_0 = tmp;
158 words when_false_1 = tmp+num_current_words;
159 words when_true_0 = tmp+2*num_current_words;
160 words when_true_1 = tmp+3*num_current_words;
161 check_bool_init (exp0, before, when_false_0, when_true_0);
162 INTERSECT (before, when_false_0, when_true_0);
163 check_bool_init (exp1, before, when_false_1, when_true_1);
164
165 INTERSECT (before, when_false_1, when_true_1);
166
167 if (code == EQ_EXPR)
168 {
169 /* Now set:
170 * when_true = (when_false_1 INTERSECTION when_true_1)
171 * UNION (when_true_0 INTERSECTION when_false_1)
172 * UNION (when_false_0 INTERSECTION when_true_1);
173 * using when_false and before as temporary working areas. */
174 INTERSECT (when_true, when_true_0, when_false_1);
175 INTERSECT (when_false, when_true_0, when_false_1);
176 UNION (when_true, when_true, when_false);
177 UNION (when_true, when_true, before);
178
179 /* Now set:
180 * when_false = (when_false_1 INTERSECTION when_true_1)
181 * UNION (when_true_0 INTERSECTION when_true_1)
182 * UNION (when_false_0 INTERSECTION when_false_1);
183 * using before as a temporary working area. */
184 INTERSECT (when_false, when_true_0, when_true_1);
185 UNION (when_false, when_false, before);
186 INTERSECT (before, when_false_0, when_false_1);
187 UNION (when_false, when_false, before);
188 }
189 else if (code == BIT_AND_EXPR || code == TRUTH_AND_EXPR)
190 {
191 UNION (when_true, when_true_0, when_true_1);
192 INTERSECT (when_false, when_false_0, when_false_1);
193 UNION (when_false, when_false, before);
194 }
195 else /* if (code == BIT_IOR_EXPR || code == TRUTH_OR_EXPR) */
196 {
197 UNION (when_false, when_false_0, when_false_1);
198 INTERSECT (when_true, when_true_0, when_true_1);
199 UNION (when_true, when_true, before);
200 }
201
202 if (tmp != buf)
203 FREE_WORDS (tmp);
204 }
205
206 /* Check a boolean expression EXP for definite assignment.
207 BEFORE is the set of variables definitely assigned before the conditional.
208 (This bitstring may be modified arbitrarily in this function.)
209 On output, WHEN_FALSE is the set of variables definitely assigned after
210 the conditional when the conditional is false.
211 On output, WHEN_TRUE is the set of variables definitely assigned after
212 the conditional when the conditional is true.
213 (WHEN_FALSE and WHEN_TRUE are overwritten with initial values ignored.)
214 (None of BEFORE, WHEN_FALSE, or WHEN_TRUE can overlap, as they may
215 be used as temporary working areas. */
216
217 static void
218 check_bool_init (exp, before, when_false, when_true)
219 tree exp;
220 words before, when_false, when_true;
221 {
222 switch (TREE_CODE (exp))
223 {
224 case COND_EXPR:
225 check_cond_init (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
226 TREE_OPERAND (exp, 2),
227 before, when_false, when_true);
228 return;
229
230 case TRUTH_ANDIF_EXPR:
231 check_cond_init (TREE_OPERAND (exp, 0),
232 TREE_OPERAND (exp, 1), boolean_false_node,
233 before, when_false, when_true);
234 return;
235 case TRUTH_ORIF_EXPR:
236 check_cond_init (TREE_OPERAND (exp, 0),
237 boolean_true_node, TREE_OPERAND (exp, 1),
238 before, when_false, when_true);
239 return;
240 case TRUTH_NOT_EXPR:
241 check_bool_init (TREE_OPERAND (exp, 0), before, when_true, when_false);
242 return;
243 case MODIFY_EXPR:
244 {
245 tree tmp = TREE_OPERAND (exp, 0);
246 if (TREE_CODE (tmp) == VAR_DECL && ! FIELD_STATIC (tmp))
247 {
248 int index;
249 check_bool_init (TREE_OPERAND (exp, 1), before,
250 when_false, when_true);
251 index = DECL_BIT_INDEX (tmp);
252 if (index >= 0)
253 {
254 SET_BIT (when_false, index);
255 SET_BIT (when_true, index);
256 }
257 break;
258 }
259 }
260 goto do_default;
261
262 case BIT_AND_EXPR:
263 case BIT_IOR_EXPR:
264 case TRUTH_AND_EXPR:
265 case TRUTH_OR_EXPR:
266 case EQ_EXPR:
267 check_bool2_init (TREE_CODE (exp),
268 TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
269 before, when_false, when_true);
270 return;
271
272 case TRUTH_XOR_EXPR:
273 case BIT_XOR_EXPR:
274 case NE_EXPR:
275 /* Just like EQ_EXPR, but switch when_true and when_false. */
276 check_bool2_init (EQ_EXPR, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
277 before, when_true, when_false);
278
279 return;
280
281 case INTEGER_CST:
282 if (integer_zerop (exp))
283 {
284 SET_ALL (when_true);
285 COPY (when_false, before);
286 }
287 else
288 {
289 SET_ALL (when_false);
290 COPY (when_true, before);
291 }
292 break;
293 default:
294 do_default:
295 check_init (exp, before);
296 COPY (when_false, before);
297 COPY (when_true, before);
298 }
299 }
300
301 /* Used to keep track of control flow branches. */
302
303 struct alternatives
304 {
305 struct alternatives *outer;
306
307 /* The value of num_current_locals at the start of this compound. */
308 int num_locals;
309
310 /* The value of the "before" set at the start of the control stucture.
311 Used for SWITCH_EXPR but not set for LABELED_BLOCK_EXPR. */
312 words saved;
313
314 int save_start_current_locals;
315
316 /* If num_current_words==1, combined==&one_word, for efficiency. */
317 word one_word;
318
319 /* The intersection of the "after" sets from previous branches. */
320 words combined;
321
322 tree block;
323 };
324
325 struct alternatives * alternatives = NULL;
326
327 #define BEGIN_ALTERNATIVES(before, current) \
328 { \
329 current.saved = NULL; \
330 current.num_locals = num_current_locals; \
331 current.combined = num_current_words <= 1 ? &current.one_word \
332 : ALLOC_WORDS (num_current_words); \
333 SET_ALL (current.combined); \
334 current.outer = alternatives; \
335 alternatives = &current; \
336 current.save_start_current_locals = start_current_locals; \
337 start_current_locals = num_current_locals; \
338 }
339
340 static void
341 done_alternative (after, current)
342 words after;
343 struct alternatives *current;
344 {
345 INTERSECTN (current->combined, current->combined, after,
346 WORDS_NEEDED (current->num_locals));
347 }
348
349 #define END_ALTERNATIVES(after, current) \
350 { \
351 alternatives = current.outer; \
352 COPY (after, current.combined); \
353 if (current.combined != &current.one_word) \
354 FREE_WORDS (current.combined); \
355 start_current_locals = current.save_start_current_locals; \
356 }
357
358 /* Check for (un)initialized local variables in EXP. */
359
360 static void
361 check_init (exp, before)
362 tree exp;
363 words before;
364 {
365 tree tmp;
366 again:
367 switch (TREE_CODE (exp))
368 {
369 case VAR_DECL:
370 if (! FIELD_STATIC (exp) && DECL_NAME (exp) != NULL_TREE)
371 {
372 int index = DECL_BIT_INDEX (exp);
373 if (index >= 0 && ! SET_P (before, index))
374 {
375 parse_error_context
376 (wfl, "Variable `%s' may not have been initialized",
377 IDENTIFIER_POINTER (DECL_NAME (exp)));
378 /* Suppress further errors. */
379 DECL_BIT_INDEX (exp) = -1;
380 }
381 }
382 break;
383 case MODIFY_EXPR:
384 tmp = TREE_OPERAND (exp, 0);
385 /* We're interested in variable declaration and parameter
386 declaration when they're declared with the `final' modifier. */
387 if ((TREE_CODE (tmp) == VAR_DECL && ! FIELD_STATIC (tmp))
388 || (TREE_CODE (tmp) == PARM_DECL && LOCAL_FINAL_P (tmp)))
389 {
390 int index;
391 check_init (TREE_OPERAND (exp, 1), before);
392 index = DECL_BIT_INDEX (tmp);
393 /* A final local already assigned or a final parameter
394 assigned must be reported as errors */
395 if (LOCAL_FINAL_P (tmp)
396 && (index == -1 || TREE_CODE (tmp) == PARM_DECL))
397 parse_error_context (wfl, "Can't assign here a value to the `final' variable `%s'", IDENTIFIER_POINTER (DECL_NAME (tmp)));
398
399 if (index >= 0)
400 SET_BIT (before, index);
401 /* Minor optimization. See comment for start_current_locals. */
402 if (index >= start_current_locals
403 && index == num_current_locals - 1)
404 {
405 num_current_locals--;
406 DECL_BIT_INDEX (tmp) = -1;
407 }
408 break;
409 }
410 else
411 goto binop;
412 case BLOCK:
413 if (BLOCK_EXPR_BODY (exp))
414 {
415 tree decl = BLOCK_EXPR_DECLS (exp);
416 int words_needed;
417 word* tmp;
418 int i;
419 int save_start_current_locals = start_current_locals;
420 int save_num_current_words = num_current_words;
421 start_current_locals = num_current_locals;
422 for (; decl != NULL_TREE; decl = TREE_CHAIN (decl))
423 {
424 DECL_BIT_INDEX (decl) = num_current_locals++;
425 }
426 words_needed = WORDS_NEEDED (num_current_locals);
427 if (words_needed > num_current_words)
428 {
429 tmp = ALLOC_WORDS (words_needed);
430 COPY (tmp, before);
431 num_current_words = words_needed;
432 }
433 else
434 tmp = before;
435 for (i = start_current_locals; i < num_current_locals; i++)
436 CLEAR_BIT (tmp, i);
437 check_init (BLOCK_EXPR_BODY (exp), tmp);
438 num_current_locals = start_current_locals;
439 start_current_locals = save_start_current_locals;
440 if (tmp != before)
441 {
442 num_current_words = save_num_current_words;
443 COPY (before, tmp);
444 FREE_WORDS (tmp);
445 }
446 }
447 break;
448 case LOOP_EXPR:
449 {
450 struct alternatives alt;
451 BEGIN_ALTERNATIVES (before, alt);
452 alt.block = exp;
453 check_init (TREE_OPERAND (exp, 0), before);
454 END_ALTERNATIVES (before, alt);
455 return;
456 }
457 case EXIT_EXPR:
458 {
459 struct alternatives *alt = alternatives;
460 words tmp = ALLOC_WORDS (2 * num_current_words);
461 words when_true = tmp;
462 words when_false = tmp + num_current_words;
463 #ifdef ENABLE_JC1_CHECKING
464 if (TREE_CODE (alt->block) != LOOP_EXPR)
465 abort ();
466 #endif
467 check_bool_init (TREE_OPERAND (exp, 0), before, when_false, when_true);
468 done_alternative (when_true, alt);
469 COPY (before, when_false);
470 FREE_WORDS (tmp);
471 return;
472 }
473 case LABELED_BLOCK_EXPR:
474 {
475 struct alternatives alt;
476 BEGIN_ALTERNATIVES (before, alt);
477 alt.block = exp;
478 if (LABELED_BLOCK_BODY (exp))
479 check_init (LABELED_BLOCK_BODY (exp), before);
480 done_alternative (before, &alt);
481 END_ALTERNATIVES (before, alt);
482 return;
483 }
484 case EXIT_BLOCK_EXPR:
485 {
486 tree block = TREE_OPERAND (exp, 0);
487 struct alternatives *alt = alternatives;
488 while (alt->block != block)
489 alt = alt->outer;
490 done_alternative (before, alt);
491 SET_ALL (before);
492 return;
493 }
494 case SWITCH_EXPR:
495 {
496 struct alternatives alt;
497 check_init (TREE_OPERAND (exp, 0), before);
498 BEGIN_ALTERNATIVES (before, alt);
499 alt.saved = ALLOC_WORDS (num_current_words);
500 COPY (alt.saved, before);
501 alt.block = exp;
502 check_init (TREE_OPERAND (exp, 1), before);
503 done_alternative (before, &alt);
504 FREE_WORDS (alt.saved);
505 END_ALTERNATIVES (before, alt);
506 return;
507 }
508 case CASE_EXPR:
509 case DEFAULT_EXPR:
510 {
511 int i;
512 struct alternatives *alt = alternatives;
513 while (TREE_CODE (alt->block) != SWITCH_EXPR)
514 alt = alt->outer;
515 COPYN (before, alt->saved, WORDS_NEEDED (alt->num_locals));
516 for (i = alt->num_locals; i < num_current_locals; i++)
517 CLEAR_BIT (before, i);
518 break;
519 }
520
521 case CLEANUP_POINT_EXPR:
522 {
523 struct alternatives alt;
524 BEGIN_ALTERNATIVES (before, alt);
525 CLEAR_ALL (alt.combined);
526 check_init (TREE_OPERAND (exp, 0), before);
527 UNION (alt.combined, alt.combined, before);
528 END_ALTERNATIVES (before, alt);
529 }
530 return;
531 case WITH_CLEANUP_EXPR:
532 {
533 struct alternatives *alt = alternatives;
534 #ifdef ENABLE_JC1_CHECKING
535 if (TREE_CODE (alt->block) != CLEANUP_POINT_EXPR)
536 abort ();
537 #endif
538 check_init (TREE_OPERAND (exp, 0), before);
539 UNION (alt->combined, alt->combined, before);
540 check_init (TREE_OPERAND (exp, 2), alt->combined);
541 return;
542 }
543
544 case TRY_EXPR:
545 {
546 tree try_clause = TREE_OPERAND (exp, 0);
547 tree clause = TREE_OPERAND (exp, 1);
548 words save = ALLOC_WORDS (num_current_words);
549 words tmp = ALLOC_WORDS (num_current_words);
550 struct alternatives alt;
551 BEGIN_ALTERNATIVES (before, alt);
552 COPY (save, before);
553 COPY (tmp, save);
554 check_init (try_clause, tmp);
555 done_alternative (tmp, &alt);
556 for ( ; clause != NULL_TREE; clause = TREE_CHAIN (clause))
557 {
558 tree catch_clause = TREE_OPERAND (clause, 0);
559 COPY (tmp, save);
560 check_init (catch_clause, tmp);
561 done_alternative (tmp, &alt);
562 }
563 FREE_WORDS (tmp);
564 FREE_WORDS (save);
565 END_ALTERNATIVES (before, alt);
566 }
567 return;
568
569 case TRY_FINALLY_EXPR:
570 {
571 words tmp = ALLOC_WORDS (num_current_words);
572 COPY (tmp, before);
573 check_init (TREE_OPERAND (exp, 0), before);
574 check_init (TREE_OPERAND (exp, 1), tmp);
575 UNION (before, before, tmp);
576 FREE_WORDS (tmp);
577 }
578 return;
579
580 case RETURN_EXPR:
581 case THROW_EXPR:
582 if (TREE_OPERAND (exp, 0))
583 check_init (TREE_OPERAND (exp, 0), before);
584 goto never_continues;
585
586 case ERROR_MARK:
587 never_continues:
588 SET_ALL (before);
589 return;
590
591 case COND_EXPR:
592 case TRUTH_ANDIF_EXPR:
593 case TRUTH_ORIF_EXPR:
594 {
595 words tmp = ALLOC_WORDS (2 * num_current_words);
596 words when_true = tmp;
597 words when_false = tmp + num_current_words;
598 check_bool_init (exp, before, when_false, when_true);
599 INTERSECT (before, when_false, when_true);
600 FREE_WORDS (tmp);
601 }
602 break;
603 case UNARY_PLUS_EXPR:
604 case NEGATE_EXPR:
605 case TRUTH_AND_EXPR:
606 case TRUTH_OR_EXPR:
607 case TRUTH_XOR_EXPR:
608 case TRUTH_NOT_EXPR:
609 case BIT_NOT_EXPR:
610 case CONVERT_EXPR:
611 case COMPONENT_REF:
612 case BIT_FIELD_REF:
613 case NOP_EXPR:
614 case FLOAT_EXPR:
615 case FIX_TRUNC_EXPR:
616 case INDIRECT_REF:
617 case ADDR_EXPR:
618 case PREDECREMENT_EXPR:
619 case PREINCREMENT_EXPR:
620 case POSTDECREMENT_EXPR:
621 case POSTINCREMENT_EXPR:
622 case NON_LVALUE_EXPR:
623 case INSTANCEOF_EXPR:
624 case FIX_CEIL_EXPR:
625 case FIX_FLOOR_EXPR:
626 case FIX_ROUND_EXPR:
627 case EXPON_EXPR:
628 case ABS_EXPR:
629 case FFS_EXPR:
630 /* Avoid needless recursion. */
631 exp = TREE_OPERAND (exp, 0);
632 goto again;
633
634 case SAVE_EXPR:
635 if (IS_INIT_CHECKED (exp))
636 return;
637 IS_INIT_CHECKED (exp) = 1;
638 exp = TREE_OPERAND (exp, 0);
639 goto again;
640
641 case COMPOUND_EXPR:
642 case PLUS_EXPR:
643 case MINUS_EXPR:
644 case MULT_EXPR:
645 case TRUNC_DIV_EXPR:
646 case TRUNC_MOD_EXPR:
647 case RDIV_EXPR:
648 case LSHIFT_EXPR:
649 case RSHIFT_EXPR:
650 case URSHIFT_EXPR:
651 case BIT_AND_EXPR:
652 case BIT_XOR_EXPR:
653 case BIT_IOR_EXPR:
654 case EQ_EXPR:
655 case NE_EXPR:
656 case GT_EXPR:
657 case GE_EXPR:
658 case LT_EXPR:
659 case LE_EXPR:
660 case MAX_EXPR:
661 case MIN_EXPR:
662 case ARRAY_REF:
663 case LROTATE_EXPR:
664 case RROTATE_EXPR:
665 case CEIL_DIV_EXPR:
666 case FLOOR_DIV_EXPR:
667 case ROUND_DIV_EXPR:
668 case CEIL_MOD_EXPR:
669 case FLOOR_MOD_EXPR:
670 case ROUND_MOD_EXPR:
671 case EXACT_DIV_EXPR:
672 binop:
673 check_init (TREE_OPERAND (exp, 0), before);
674 /* Avoid needless recursion, especially for COMPOUND_EXPR. */
675 exp = TREE_OPERAND (exp, 1);
676 goto again;
677
678 case PARM_DECL:
679 case RESULT_DECL:
680 case FUNCTION_DECL:
681 case INTEGER_CST:
682 case REAL_CST:
683 case STRING_CST:
684 case EXC_PTR_EXPR:
685 break;
686
687 case NEW_CLASS_EXPR:
688 case CALL_EXPR:
689 {
690 tree func = TREE_OPERAND (exp, 0);
691 tree x = TREE_OPERAND (exp, 1);
692 if (TREE_CODE (func) == ADDR_EXPR)
693 func = TREE_OPERAND (func, 0);
694 check_init (func, before);
695
696 for ( ; x != NULL_TREE; x = TREE_CHAIN (x))
697 check_init (TREE_VALUE (x), before);
698 if (func == throw_node)
699 goto never_continues;
700 }
701 break;
702
703 case NEW_ARRAY_INIT:
704 {
705 tree x = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
706 for ( ; x != NULL_TREE; x = TREE_CHAIN (x))
707 check_init (TREE_VALUE (x), before);
708 }
709 break;
710
711 case EXPR_WITH_FILE_LOCATION:
712 {
713 const char *saved_input_filename = input_filename;
714 tree saved_wfl = wfl;
715 tree body = EXPR_WFL_NODE (exp);
716 int saved_lineno = lineno;
717 if (body == empty_stmt_node)
718 break;
719 wfl = exp;
720 input_filename = EXPR_WFL_FILENAME (exp);
721 lineno = EXPR_WFL_LINENO (exp);
722 check_init (body, before);
723 input_filename = saved_input_filename;
724 lineno = saved_lineno;
725 wfl = saved_wfl;
726 }
727 break;
728
729 default:
730 internal_error
731 ("internal error in check-init: tree code not implemented: %s",
732 tree_code_name [(int) TREE_CODE (exp)]);
733 }
734 }
735
736 void
737 check_for_initialization (body)
738 tree body;
739 {
740 word before = 0;
741 check_init (body, &before);
742 }