OSDN Git Service

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