OSDN Git Service

2000-02-25 Anthony Green <green@cygnus.com>
[pf3gnuchains/gcc-fork.git] / gcc / java / check-init.c
1 /* Code to test for "definitive assignment".
2
3    Copyright (C) 1999, 2000  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 /* 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
362 static void
363 check_init (exp, before)
364      tree exp;
365      words before;
366 {
367   tree tmp;
368  again:
369   switch (TREE_CODE (exp))
370     {
371     case VAR_DECL:
372       if (! FIELD_STATIC (exp) && DECL_NAME (exp) != NULL_TREE)
373         {
374           int index = DECL_BIT_INDEX (exp);
375           if (index >= 0 && ! SET_P (before, index))
376             {
377 #if 1
378               parse_error_context (wfl,
379                                    "Variable `%s' may not have been initialized"
380                                    , IDENTIFIER_POINTER (DECL_NAME (exp)));
381 #else
382               error_with_decl (exp, "variable may be used uninitialized");
383 #endif
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       if (TREE_CODE (tmp) == VAR_DECL && ! FIELD_STATIC (tmp))
392         {
393           int index;
394           check_init (TREE_OPERAND (exp, 1), before);
395           index = DECL_BIT_INDEX (tmp);
396           if (index >= 0)
397             SET_BIT (before, index);
398           /* Minor optimization.  See comment for start_current_locals. */
399           if (index >= start_current_locals
400               && index == num_current_locals - 1)
401             {
402               num_current_locals--;
403               DECL_BIT_INDEX (tmp) = -1;
404             }
405          break;
406        }
407      else
408        goto binop;
409     case BLOCK:
410       if (BLOCK_EXPR_BODY (exp))
411         {
412           tree decl = BLOCK_EXPR_DECLS (exp);
413           int words_needed;
414           word* tmp;
415           int i;
416           int save_start_current_locals = start_current_locals;
417           int save_num_current_words = num_current_words;
418           start_current_locals = num_current_locals;
419           for (;  decl != NULL_TREE;  decl = TREE_CHAIN (decl))
420             {
421               DECL_BIT_INDEX (decl) = num_current_locals++;
422             }
423           words_needed = WORDS_NEEDED (num_current_locals);
424           if (words_needed > num_current_words)
425             {
426               tmp = ALLOC_WORDS (words_needed);
427               COPY (tmp, before);
428               num_current_words = words_needed;
429             }
430           else
431             tmp = before;
432           for (i = start_current_locals;  i < num_current_locals;  i++)
433             CLEAR_BIT (tmp, i);
434           check_init (BLOCK_EXPR_BODY (exp), tmp);
435           num_current_locals = start_current_locals;
436           start_current_locals = save_start_current_locals;
437           if (tmp != before)
438             {
439               num_current_words = save_num_current_words;
440               COPY (before, tmp);
441               FREE_WORDS (tmp);
442             }
443         }
444       break;
445     case LOOP_EXPR:
446       {
447         struct alternatives alt;
448         BEGIN_ALTERNATIVES (before, alt);
449         alt.block = exp;
450         check_init (TREE_OPERAND (exp, 0), before);
451         done_alternative (before, &alt);
452         END_ALTERNATIVES (before, alt);
453         return;
454       }
455     case EXIT_EXPR:
456       {
457         struct alternatives *alt = alternatives;
458         words tmp = ALLOC_WORDS (2 * num_current_words);
459         words when_true = tmp;
460         words when_false = tmp + num_current_words;
461 #ifdef ENABLE_CHECKING
462         if (TREE_CODE (alt->block) != LOOP_EXPR)
463           fatal ("internal error in check-init:  EXIT_EXPR not in LOOP_EXPR");
464 #endif
465         check_bool_init (TREE_OPERAND (exp, 0), before, when_false, when_true);
466         done_alternative (when_true, alt);
467         COPY (before, when_false);
468         FREE_WORDS (tmp);
469         return;
470       }
471     case LABELED_BLOCK_EXPR:
472       {
473         struct alternatives alt;
474         BEGIN_ALTERNATIVES (before, alt);
475         alt.block = exp;
476         if (LABELED_BLOCK_BODY (exp))
477           check_init (LABELED_BLOCK_BODY (exp), before);
478         done_alternative (before, &alt);
479         END_ALTERNATIVES (before, alt);
480         return;
481       }
482     case EXIT_BLOCK_EXPR:
483       {
484         tree block = TREE_OPERAND (exp, 0);
485         struct alternatives *alt = alternatives;
486         while (alt->block != block)
487           alt = alt->outer;
488         done_alternative (before, alt);
489         SET_ALL (before);
490         return;
491       }
492     case SWITCH_EXPR:
493       {
494         struct alternatives alt;
495         check_init (TREE_OPERAND (exp, 0), before);
496         BEGIN_ALTERNATIVES (before, alt);
497         alt.saved = ALLOC_WORDS (num_current_words);
498         COPY (alt.saved, before);
499         alt.block = exp;
500         check_init (TREE_OPERAND (exp, 1), before);
501         done_alternative (before, &alt);
502         FREE_WORDS (alt.saved);
503         END_ALTERNATIVES (before, alt);
504         return;
505       }
506     case CASE_EXPR:
507     case DEFAULT_EXPR:
508       {
509         int i;
510         struct alternatives *alt = alternatives;
511         while (TREE_CODE (alt->block) != SWITCH_EXPR)
512           alt = alt->outer;
513         COPYN (before, alt->saved, WORDS_NEEDED (alt->num_locals));
514         for (i = alt->num_locals;  i < num_current_locals;  i++)
515           CLEAR_BIT (before, i);
516         break;
517       }
518
519     case CLEANUP_POINT_EXPR:
520       {
521         struct alternatives alt;
522         BEGIN_ALTERNATIVES (before, alt);
523         CLEAR_ALL (alt.combined);
524         check_init (TREE_OPERAND (exp, 0), before); 
525         UNION (alt.combined, alt.combined, before);
526         END_ALTERNATIVES (before, alt);
527       }
528       return;
529     case WITH_CLEANUP_EXPR:
530       {
531         struct alternatives *alt = alternatives;        
532 #ifdef ENABLE_CHECKING
533         if (TREE_CODE (alt->block) != CLEANUP_POINT_EXPR)
534           fatal ("internal error in check-init:  WITH_CLEANUP_EXPR not in CLEANUP_POINT_EXPR");
535 #endif
536         check_init (TREE_OPERAND (exp, 0), before);
537         UNION (alt->combined, alt->combined, before);
538         check_init (TREE_OPERAND (exp, 2), alt->combined);
539         return;
540       }
541
542     case TRY_EXPR:
543       {
544         tree try_clause = TREE_OPERAND (exp, 0);
545         tree clause = TREE_OPERAND (exp, 1);
546         words save = ALLOC_WORDS (num_current_words);
547         words tmp = ALLOC_WORDS (num_current_words);
548         struct alternatives alt;
549         BEGIN_ALTERNATIVES (before, alt);
550         COPY (save, before);
551         COPY (tmp, save);
552         check_init (try_clause, tmp);
553         done_alternative (tmp, &alt);
554         for ( ; clause != NULL_TREE;  clause = TREE_CHAIN (clause))
555           {
556             tree catch_clause = TREE_OPERAND (clause, 0);
557             COPY (tmp, save);
558             check_init (catch_clause, tmp);
559             done_alternative (tmp, &alt);
560           }
561         FREE_WORDS (tmp);
562         FREE_WORDS (save);
563         END_ALTERNATIVES (before, alt);
564       }
565     return;
566
567     case TRY_FINALLY_EXPR:
568       {
569         words tmp = ALLOC_WORDS (num_current_words);
570         COPY (tmp, before);
571         check_init (TREE_OPERAND (exp, 0), tmp);
572         check_init (TREE_OPERAND (exp, 1), before);
573         FREE_WORDS (tmp);
574       }
575       return;
576
577     case RETURN_EXPR:
578     case THROW_EXPR:
579       if (TREE_OPERAND (exp, 0))
580         check_init (TREE_OPERAND (exp, 0), before);
581       goto never_continues;
582
583     case ERROR_MARK:
584     never_continues:
585       SET_ALL (before);
586       return;
587       
588     case COND_EXPR:
589     case TRUTH_ANDIF_EXPR:
590     case TRUTH_ORIF_EXPR:
591       {
592         words tmp = ALLOC_WORDS (2 * num_current_words);
593         words when_true = tmp;
594         words when_false = tmp + num_current_words;
595         check_bool_init (exp, before, when_false, when_true);
596         INTERSECT (before, when_false, when_true);
597         FREE_WORDS (tmp);
598       }
599       break;
600     case UNARY_PLUS_EXPR:
601     case NEGATE_EXPR:
602     case TRUTH_AND_EXPR:
603     case TRUTH_OR_EXPR:
604     case TRUTH_XOR_EXPR:
605     case TRUTH_NOT_EXPR:
606     case BIT_NOT_EXPR:
607     case CONVERT_EXPR:
608     case COMPONENT_REF:
609     case NOP_EXPR:
610     case FLOAT_EXPR:
611     case FIX_TRUNC_EXPR:
612     case INDIRECT_REF:
613     case ADDR_EXPR:
614     case SAVE_EXPR:
615     case PREDECREMENT_EXPR:
616     case PREINCREMENT_EXPR:
617     case POSTDECREMENT_EXPR:
618     case POSTINCREMENT_EXPR:
619     case NON_LVALUE_EXPR:
620     case INSTANCEOF_EXPR:
621       /* Avoid needless recursion. */
622       exp = TREE_OPERAND (exp, 0);
623       goto again;
624
625     case COMPOUND_EXPR:
626     case PLUS_EXPR:
627     case MINUS_EXPR:
628     case MULT_EXPR:
629     case TRUNC_DIV_EXPR:
630     case TRUNC_MOD_EXPR:
631     case RDIV_EXPR:
632     case LSHIFT_EXPR:
633     case RSHIFT_EXPR:
634     case URSHIFT_EXPR:
635     case BIT_AND_EXPR:
636     case BIT_XOR_EXPR:
637     case BIT_IOR_EXPR:
638     case EQ_EXPR: 
639     case NE_EXPR:
640     case GT_EXPR:
641     case GE_EXPR:
642     case LT_EXPR:
643     case LE_EXPR:
644     case MAX_EXPR:
645     case MIN_EXPR:
646     case ARRAY_REF:
647     binop:
648       check_init (TREE_OPERAND (exp, 0), before);
649       /* Avoid needless recursion, especially for COMPOUND_EXPR. */
650       exp = TREE_OPERAND (exp, 1);
651       goto again;
652
653     case PARM_DECL:
654     case RESULT_DECL:
655     case FUNCTION_DECL:
656     case INTEGER_CST:
657     case REAL_CST:
658     case STRING_CST:
659       break;
660
661     case NEW_CLASS_EXPR:
662     case CALL_EXPR:
663       {
664         tree func = TREE_OPERAND (exp, 0);
665         tree x = TREE_OPERAND (exp, 1);
666         if (TREE_CODE (func) == ADDR_EXPR)
667           func = TREE_OPERAND (func, 0);
668         check_init (func, before);
669
670         for ( ;  x != NULL_TREE;  x = TREE_CHAIN (x))
671           check_init (TREE_VALUE (x), before);
672         if (func == throw_node[0]
673             || func == throw_node[1])
674           goto never_continues;
675       }
676       break;
677
678     case NEW_ARRAY_INIT:
679       {
680         tree x = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
681         for ( ;  x != NULL_TREE;  x = TREE_CHAIN (x))
682           check_init (TREE_VALUE (x), before);
683       }
684       break;
685
686     case EXPR_WITH_FILE_LOCATION:
687       {
688         char *saved_input_filename = input_filename;
689         tree saved_wfl = wfl;
690         tree body = EXPR_WFL_NODE (exp);
691         int saved_lineno = lineno;
692         if (body == empty_stmt_node)
693           break;
694         wfl = exp;
695         input_filename = EXPR_WFL_FILENAME (exp);
696         lineno = EXPR_WFL_LINENO (exp);
697         check_init (body, before);
698         input_filename = saved_input_filename;
699         lineno = saved_lineno;
700         wfl = saved_wfl;
701       }
702       break;
703       
704     default:
705       fatal ("internal error in check-init: tree code not implemented: %s",
706             tree_code_name [(int) TREE_CODE (exp)]);
707     }
708 }
709
710 void
711 check_for_initialization (body)
712      tree body;
713 {
714   word before = 0;
715   check_init (body, &before);
716 }