OSDN Git Service

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