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