00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026 #include "system.h"
00027 #include "tree.h"
00028 #include "flags.h"
00029 #include "java-tree.h"
00030 #include "toplev.h"
00031
00032
00033
00034
00035
00036
00037
00038
00039 typedef unsigned int word;
00040
00041
00042 typedef word *words;
00043
00044
00045 static int num_current_locals = 0;
00046
00047
00048
00049 static int loop_current_locals;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 static int start_current_locals = 0;
00072
00073 static int num_current_words;
00074
00075 static tree wfl;
00076
00077 #define COPYN(DST, SRC, NWORDS) memcpy (DST, SRC, NWORDS * sizeof(word))
00078 #define COPY(DST, SRC) COPYN (DST, SRC, num_current_words)
00079
00080 #define SET_ALL(DST) memset (DST, ~0, num_current_words * sizeof(word))
00081 #define CLEAR_ALL(DST) memset (DST, 0, num_current_words * sizeof(word))
00082
00083 #define INTERSECTN(DST, SRC1, SRC2, N) \
00084 do { int n = N; \
00085 while (--n >= 0) DST[n] = SRC1[n] & SRC2[n]; \
00086 } while (0)
00087
00088 #define UNION(DST, SRC1, SRC2) \
00089 UNIONN (DST, SRC1, SRC2, num_current_words)
00090
00091 #define UNIONN(DST, SRC1, SRC2, N) \
00092 do { int n = N; \
00093 while (--n >= 0) DST[n] = SRC1[n] | SRC2[n]; \
00094 } while (0)
00095
00096 #define INTERSECT(DST, SRC1, SRC2) \
00097 INTERSECTN (DST, SRC1, SRC2, num_current_words)
00098
00099 #define WORD_SIZE ((unsigned int)(sizeof(word) * BITS_PER_UNIT))
00100
00101 static void check_bool_init PARAMS ((tree, words, words, words));
00102 static void check_init PARAMS ((tree, words));
00103 static void check_cond_init PARAMS ((tree, tree, tree, words, words, words));
00104 static void check_bool2_init PARAMS ((enum tree_code, tree, tree, words, words, words));
00105 struct alternatives;
00106 static void done_alternative PARAMS ((words, struct alternatives *));
00107 static tree get_variable_decl PARAMS ((tree));
00108 static void final_assign_error PARAMS ((tree));
00109 static void check_final_reassigned PARAMS ((tree, words));
00110
00111 #define ALLOC_WORDS(NUM) ((word*) xmalloc ((NUM) * sizeof (word)))
00112 #define FREE_WORDS(PTR) (free (PTR))
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 #define DECLARE_BUFFERS(BUFFER, NUMBUFFERS) \
00124 word BUFFER##_short[2 * NUMBUFFERS]; \
00125 words BUFFER = ALLOC_BUFFER(BUFFER##_short, NUMBUFFERS * num_current_words)
00126
00127 #define RELEASE_BUFFERS(BUFFER) \
00128 FREE_BUFFER(BUFFER, BUFFER##_short)
00129
00130 #define ALLOC_BUFFER(SHORTBUFFER, NUMWORDS) \
00131 ((NUMWORDS) * sizeof(word) <= sizeof(SHORTBUFFER) ? SHORTBUFFER \
00132 : ALLOC_WORDS(NUMWORDS))
00133
00134 #define FREE_BUFFER(BUFFER, SHORTBUFFER) \
00135 if (BUFFER != SHORTBUFFER) FREE_WORDS(BUFFER)
00136
00137 #define SET_P(WORDS, BIT) \
00138 (WORDS[(BIT) / WORD_SIZE] & (1 << ((BIT) % WORD_SIZE)))
00139
00140 #define CLEAR_BIT(WORDS, BIT) \
00141 (WORDS[(BIT) / WORD_SIZE] &= ~ (1 << ((BIT) % WORD_SIZE)))
00142
00143 #define SET_BIT(WORDS, BIT) \
00144 (WORDS[(BIT) / WORD_SIZE] |= (1 << ((BIT) % WORD_SIZE)))
00145
00146 #define WORDS_NEEDED(BITS) (((BITS)+(WORD_SIZE-1))/(WORD_SIZE))
00147
00148 #define ASSIGNED_P(WORDS, BIT) SET_P(WORDS, 2 * (BIT))
00149 #define UNASSIGNED_P(WORDS, BIT) SET_P(WORDS, 2 * (BIT) + 1)
00150
00151 #define SET_ASSIGNED(WORDS, INDEX) SET_BIT (WORDS, 2 * (INDEX))
00152 #define SET_UNASSIGNED(WORDS, INDEX) SET_BIT (WORDS, 2 * (INDEX) + 1)
00153
00154 #define CLEAR_ASSIGNED(WORDS, INDEX) CLEAR_BIT (WORDS, 2 * (INDEX))
00155 #define CLEAR_UNASSIGNED(WORDS, INDEX) CLEAR_BIT (WORDS, 2 * (INDEX) + 1)
00156
00157
00158
00159
00160 static tree
00161 get_variable_decl (exp)
00162 tree exp;
00163 {
00164 if (TREE_CODE (exp) == VAR_DECL)
00165 {
00166 if (! TREE_STATIC (exp) || FIELD_FINAL (exp))
00167 return exp;
00168 }
00169
00170 else if (TREE_CODE (exp) == PARM_DECL)
00171 {
00172 if (DECL_FINAL (exp))
00173 return exp;
00174 }
00175
00176 else if (TREE_CODE (exp) == COMPONENT_REF)
00177 {
00178 tree op0 = TREE_OPERAND (exp, 0);
00179 tree op1 = TREE_OPERAND (exp, 1);
00180 tree mdecl = current_function_decl;
00181 if (TREE_CODE (op0) == INDIRECT_REF
00182 && TREE_CODE (op1) == FIELD_DECL
00183 && ! METHOD_STATIC (mdecl)
00184 && FIELD_FINAL (op1))
00185 {
00186 op0 = TREE_OPERAND (op0, 0);
00187 if (op0 == BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)))
00188 return op1;
00189 }
00190 }
00191 return NULL_TREE;
00192 }
00193
00194 static void
00195 final_assign_error (name)
00196 tree name;
00197 {
00198 static const char format[]
00199 = "can't reassign a value to the final variable '%s'";
00200 parse_error_context (wfl, format, IDENTIFIER_POINTER (name));
00201 }
00202
00203 static void
00204 check_final_reassigned (decl, before)
00205 tree decl;
00206 words before;
00207 {
00208 int index = DECL_BIT_INDEX (decl);
00209
00210
00211 if (DECL_FINAL (decl) && index != -2
00212 && (index < loop_current_locals
00213 || ! UNASSIGNED_P (before, index)))
00214 {
00215 final_assign_error (DECL_NAME (decl));
00216 }
00217 }
00218
00219
00220
00221
00222
00223 static void
00224 check_cond_init (test_exp, then_exp, else_exp,
00225 before, when_false, when_true)
00226 tree test_exp, then_exp, else_exp;
00227 words before, when_false, when_true;
00228 {
00229 int save_start_current_locals = start_current_locals;
00230 DECLARE_BUFFERS(test_false, 6);
00231 words test_true = test_false + num_current_words;
00232 words then_false = test_true + num_current_words;
00233 words then_true = then_false + num_current_words;
00234 words else_false = then_true + num_current_words;
00235 words else_true = else_false + num_current_words;
00236 start_current_locals = num_current_locals;
00237
00238 check_bool_init (test_exp, before, test_false, test_true);
00239 check_bool_init (then_exp, test_true, then_false, then_true);
00240 check_bool_init (else_exp, test_false, else_false, else_true);
00241 INTERSECT (when_false, then_false, else_false);
00242 INTERSECT (when_true, then_true, else_true);
00243 RELEASE_BUFFERS(test_false);
00244 start_current_locals = save_start_current_locals;
00245 }
00246
00247
00248
00249
00250
00251 static void
00252 check_bool2_init (code, exp0, exp1, before, when_false, when_true)
00253 enum tree_code code; tree exp0, exp1;
00254 words before, when_false, when_true;
00255 {
00256 word buf[2*4];
00257 words tmp = num_current_words <= 2 ? buf
00258 : ALLOC_WORDS (4 * num_current_words);
00259 words when_false_0 = tmp;
00260 words when_false_1 = tmp+num_current_words;
00261 words when_true_0 = tmp+2*num_current_words;
00262 words when_true_1 = tmp+3*num_current_words;
00263 check_bool_init (exp0, before, when_false_0, when_true_0);
00264 INTERSECT (before, when_false_0, when_true_0);
00265 check_bool_init (exp1, before, when_false_1, when_true_1);
00266
00267 INTERSECT (before, when_false_1, when_true_1);
00268
00269 if (code == EQ_EXPR)
00270 {
00271
00272
00273
00274
00275
00276 INTERSECT (when_true, when_true_0, when_false_1);
00277 INTERSECT (when_false, when_true_0, when_false_1);
00278 UNION (when_true, when_true, when_false);
00279 UNION (when_true, when_true, before);
00280
00281
00282
00283
00284
00285
00286 INTERSECT (when_false, when_true_0, when_true_1);
00287 UNION (when_false, when_false, before);
00288 INTERSECT (before, when_false_0, when_false_1);
00289 UNION (when_false, when_false, before);
00290 }
00291 else if (code == BIT_AND_EXPR || code == TRUTH_AND_EXPR)
00292 {
00293 UNION (when_true, when_true_0, when_true_1);
00294 INTERSECT (when_false, when_false_0, when_false_1);
00295 UNION (when_false, when_false, before);
00296 }
00297 else
00298 {
00299 UNION (when_false, when_false_0, when_false_1);
00300 INTERSECT (when_true, when_true_0, when_true_1);
00301 UNION (when_true, when_true, before);
00302 }
00303
00304 if (tmp != buf)
00305 FREE_WORDS (tmp);
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 static void
00320 check_bool_init (exp, before, when_false, when_true)
00321 tree exp;
00322 words before, when_false, when_true;
00323 {
00324 switch (TREE_CODE (exp))
00325 {
00326 case COND_EXPR:
00327 check_cond_init (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
00328 TREE_OPERAND (exp, 2),
00329 before, when_false, when_true);
00330 return;
00331
00332 case TRUTH_ANDIF_EXPR:
00333 check_cond_init (TREE_OPERAND (exp, 0),
00334 TREE_OPERAND (exp, 1), boolean_false_node,
00335 before, when_false, when_true);
00336 return;
00337 case TRUTH_ORIF_EXPR:
00338 check_cond_init (TREE_OPERAND (exp, 0),
00339 boolean_true_node, TREE_OPERAND (exp, 1),
00340 before, when_false, when_true);
00341 return;
00342 case TRUTH_NOT_EXPR:
00343 check_bool_init (TREE_OPERAND (exp, 0), before, when_true, when_false);
00344 return;
00345 case MODIFY_EXPR:
00346 {
00347 tree tmp = TREE_OPERAND (exp, 0);
00348 if ((tmp = get_variable_decl (tmp)) != NULL_TREE)
00349 {
00350 int index;
00351 check_bool_init (TREE_OPERAND (exp, 1), before,
00352 when_false, when_true);
00353 check_final_reassigned (tmp, before);
00354 index = DECL_BIT_INDEX (tmp);
00355 if (index >= 0)
00356 {
00357 SET_ASSIGNED (when_false, index);
00358 SET_ASSIGNED (when_true, index);
00359 CLEAR_UNASSIGNED (when_false, index);
00360 CLEAR_UNASSIGNED (when_true, index);
00361 }
00362 break;
00363 }
00364 }
00365 goto do_default;
00366
00367 case BIT_AND_EXPR:
00368 case BIT_IOR_EXPR:
00369 case TRUTH_AND_EXPR:
00370 case TRUTH_OR_EXPR:
00371 case EQ_EXPR:
00372 check_bool2_init (TREE_CODE (exp),
00373 TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
00374 before, when_false, when_true);
00375 return;
00376
00377 case TRUTH_XOR_EXPR:
00378 case BIT_XOR_EXPR:
00379 case NE_EXPR:
00380
00381 check_bool2_init (EQ_EXPR, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
00382 before, when_true, when_false);
00383
00384 return;
00385
00386 case INTEGER_CST:
00387 if (integer_zerop (exp))
00388 {
00389 SET_ALL (when_true);
00390 COPY (when_false, before);
00391 }
00392 else
00393 {
00394 SET_ALL (when_false);
00395 COPY (when_true, before);
00396 }
00397 break;
00398 default:
00399 do_default:
00400 check_init (exp, before);
00401 COPY (when_false, before);
00402 COPY (when_true, before);
00403 }
00404 }
00405
00406
00407
00408 struct alternatives
00409 {
00410 struct alternatives *outer;
00411
00412
00413 int num_locals;
00414
00415
00416
00417 words saved;
00418
00419 int save_start_current_locals;
00420
00421
00422 word one_word;
00423
00424
00425 words combined;
00426
00427 tree block;
00428 };
00429
00430 struct alternatives * alternatives = NULL;
00431
00432
00433
00434
00435
00436 #define BEGIN_ALTERNATIVES(before, current) \
00437 { \
00438 current.saved = NULL; \
00439 current.num_locals = num_current_locals; \
00440 current.combined = num_current_words <= 1 ? ¤t.one_word \
00441 : ALLOC_WORDS (num_current_words); \
00442 SET_ALL (current.combined); \
00443 current.outer = alternatives; \
00444 alternatives = ¤t; \
00445 current.save_start_current_locals = start_current_locals; \
00446 start_current_locals = num_current_locals; \
00447 }
00448
00449
00450
00451
00452
00453 static void
00454 done_alternative (after, current)
00455 words after;
00456 struct alternatives *current;
00457 {
00458 INTERSECTN (current->combined, current->combined, after,
00459 WORDS_NEEDED (2 * current->num_locals));
00460 }
00461
00462
00463
00464
00465
00466 #define END_ALTERNATIVES(after, current) \
00467 { \
00468 alternatives = current.outer; \
00469 COPY (after, current.combined); \
00470 if (current.combined != ¤t.one_word) \
00471 FREE_WORDS (current.combined); \
00472 start_current_locals = current.save_start_current_locals; \
00473 }
00474
00475
00476
00477 static void
00478 check_init (exp, before)
00479 tree exp;
00480 words before;
00481 {
00482 tree tmp;
00483 again:
00484 switch (TREE_CODE (exp))
00485 {
00486 case VAR_DECL:
00487 case PARM_DECL:
00488 if (! FIELD_STATIC (exp) && DECL_NAME (exp) != NULL_TREE
00489 && DECL_NAME (exp) != this_identifier_node)
00490 {
00491 int index = DECL_BIT_INDEX (exp);
00492
00493
00494 if (! LOCAL_CLASS_INITIALIZATION_FLAG_P (exp)
00495 && index >= 0 && ! ASSIGNED_P (before, index))
00496 {
00497 parse_error_context
00498 (wfl, "Variable `%s' may not have been initialized",
00499 IDENTIFIER_POINTER (DECL_NAME (exp)));
00500
00501 DECL_BIT_INDEX (exp) = -2;
00502 }
00503 }
00504 break;
00505
00506 case COMPONENT_REF:
00507 check_init (TREE_OPERAND (exp, 0), before);
00508 if ((tmp = get_variable_decl (exp)) != NULL_TREE)
00509 {
00510 int index = DECL_BIT_INDEX (tmp);
00511 if (index >= 0 && ! ASSIGNED_P (before, index))
00512 {
00513 parse_error_context
00514 (wfl, "variable '%s' may not have been initialized",
00515 IDENTIFIER_POINTER (DECL_NAME (tmp)));
00516
00517 DECL_BIT_INDEX (tmp) = -2;
00518 }
00519 }
00520 break;
00521
00522 case MODIFY_EXPR:
00523 tmp = TREE_OPERAND (exp, 0);
00524
00525
00526 if ((tmp = get_variable_decl (tmp)) != NULL_TREE)
00527 {
00528 int index;
00529 check_init (TREE_OPERAND (exp, 1), before);
00530 check_final_reassigned (tmp, before);
00531 index = DECL_BIT_INDEX (tmp);
00532 if (index >= 0)
00533 {
00534 SET_ASSIGNED (before, index);
00535 CLEAR_UNASSIGNED (before, index);
00536 }
00537
00538
00539
00540
00541
00542 if (! STATIC_CLASS_INIT_OPT_P ()
00543 && index >= start_current_locals
00544 && index == num_current_locals - 1)
00545 {
00546 num_current_locals--;
00547 DECL_BIT_INDEX (tmp) = -1;
00548 }
00549 break;
00550 }
00551 else if (TREE_CODE (tmp = TREE_OPERAND (exp, 0)) == COMPONENT_REF)
00552 {
00553 tree decl;
00554 check_init (tmp, before);
00555 check_init (TREE_OPERAND (exp, 1), before);
00556 decl = TREE_OPERAND (tmp, 1);
00557 if (DECL_FINAL (decl))
00558 final_assign_error (DECL_NAME (decl));
00559 break;
00560 }
00561 else if (TREE_CODE (tmp) == COMPONENT_REF && IS_ARRAY_LENGTH_ACCESS (tmp))
00562 {
00563
00564
00565 final_assign_error (length_identifier_node);
00566 }
00567 else
00568 goto binop;
00569 case BLOCK:
00570 if (BLOCK_EXPR_BODY (exp))
00571 {
00572 tree decl = BLOCK_EXPR_DECLS (exp);
00573 int words_needed;
00574 word* tmp;
00575 int i;
00576 int save_start_current_locals = start_current_locals;
00577 int save_num_current_words = num_current_words;
00578 start_current_locals = num_current_locals;
00579 for (; decl != NULL_TREE; decl = TREE_CHAIN (decl))
00580 {
00581 DECL_BIT_INDEX (decl) = num_current_locals++;
00582 }
00583 words_needed = WORDS_NEEDED (2 * num_current_locals);
00584 if (words_needed > num_current_words)
00585 {
00586 tmp = ALLOC_WORDS (words_needed);
00587 COPY (tmp, before);
00588 num_current_words = words_needed;
00589 }
00590 else
00591 tmp = before;
00592 for (i = start_current_locals; i < num_current_locals; i++)
00593 {
00594 CLEAR_ASSIGNED (tmp, i);
00595 SET_UNASSIGNED (tmp, i);
00596 }
00597 check_init (BLOCK_EXPR_BODY (exp), tmp);
00598
00599
00600 for (decl = BLOCK_EXPR_DECLS (exp);
00601 decl != NULL_TREE; decl = TREE_CHAIN (decl))
00602 {
00603 if (LOCAL_CLASS_INITIALIZATION_FLAG_P (decl))
00604 {
00605 int index = DECL_BIT_INDEX (decl);
00606 tree fndecl = DECL_CONTEXT (decl);
00607 if (fndecl && METHOD_STATIC (fndecl)
00608 && (DECL_INITIAL (decl) == boolean_true_node
00609 || (index >= 0 && ASSIGNED_P (tmp, index))))
00610 hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
00611 DECL_FUNCTION_INIT_TEST_CLASS(decl), TRUE, NULL);
00612 }
00613 DECL_BIT_INDEX (decl) = -1;
00614 }
00615
00616 num_current_locals = start_current_locals;
00617 start_current_locals = save_start_current_locals;
00618 if (tmp != before)
00619 {
00620 num_current_words = save_num_current_words;
00621 COPY (before, tmp);
00622 FREE_WORDS (tmp);
00623 }
00624 }
00625 break;
00626 case LOOP_EXPR:
00627 {
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637 struct alternatives alt;
00638 int save_loop_current_locals = loop_current_locals;
00639 int save_start_current_locals = start_current_locals;
00640 loop_current_locals = num_current_locals;
00641 start_current_locals = num_current_locals;
00642 BEGIN_ALTERNATIVES (before, alt);
00643 alt.block = exp;
00644 check_init (TREE_OPERAND (exp, 0), before);
00645 END_ALTERNATIVES (before, alt);
00646 loop_current_locals = save_loop_current_locals;
00647 start_current_locals = save_start_current_locals;
00648 return;
00649 }
00650 case EXIT_EXPR:
00651 {
00652 struct alternatives *alt = alternatives;
00653 DECLARE_BUFFERS(when_true, 2);
00654 words when_false = when_true + num_current_words;
00655 #ifdef ENABLE_JC1_CHECKING
00656 if (TREE_CODE (alt->block) != LOOP_EXPR)
00657 abort ();
00658 #endif
00659 check_bool_init (TREE_OPERAND (exp, 0), before, when_false, when_true);
00660 done_alternative (when_true, alt);
00661 COPY (before, when_false);
00662 RELEASE_BUFFERS(when_true);
00663 return;
00664 }
00665 case LABELED_BLOCK_EXPR:
00666 {
00667 struct alternatives alt;
00668 BEGIN_ALTERNATIVES (before, alt);
00669 alt.block = exp;
00670 if (LABELED_BLOCK_BODY (exp))
00671 check_init (LABELED_BLOCK_BODY (exp), before);
00672 done_alternative (before, &alt);
00673 END_ALTERNATIVES (before, alt);
00674 return;
00675 }
00676 case EXIT_BLOCK_EXPR:
00677 {
00678 tree block = TREE_OPERAND (exp, 0);
00679 struct alternatives *alt = alternatives;
00680 while (alt->block != block)
00681 alt = alt->outer;
00682 done_alternative (before, alt);
00683 SET_ALL (before);
00684 return;
00685 }
00686 case SWITCH_EXPR:
00687 {
00688 struct alternatives alt;
00689 word buf[2];
00690 check_init (TREE_OPERAND (exp, 0), before);
00691 BEGIN_ALTERNATIVES (before, alt);
00692 alt.saved = ALLOC_BUFFER(buf, num_current_words);
00693 COPY (alt.saved, before);
00694 alt.block = exp;
00695 check_init (TREE_OPERAND (exp, 1), before);
00696 done_alternative (before, &alt);
00697 if (! SWITCH_HAS_DEFAULT (exp))
00698 done_alternative (alt.saved, &alt);
00699 FREE_BUFFER(alt.saved, buf);
00700 END_ALTERNATIVES (before, alt);
00701 return;
00702 }
00703 case CASE_EXPR:
00704 case DEFAULT_EXPR:
00705 {
00706 int i;
00707 struct alternatives *alt = alternatives;
00708 while (TREE_CODE (alt->block) != SWITCH_EXPR)
00709 alt = alt->outer;
00710 COPYN (before, alt->saved, WORDS_NEEDED (2 * alt->num_locals));
00711 for (i = alt->num_locals; i < num_current_locals; i++)
00712 CLEAR_ASSIGNED (before, i);
00713 break;
00714 }
00715
00716 case TRY_EXPR:
00717 {
00718 tree try_clause = TREE_OPERAND (exp, 0);
00719 tree clause = TREE_OPERAND (exp, 1);
00720 word buf[2*2];
00721 words tmp = (num_current_words <= 2 ? buf
00722 : ALLOC_WORDS (2 * num_current_words));
00723 words save = tmp + num_current_words;
00724 struct alternatives alt;
00725 BEGIN_ALTERNATIVES (before, alt);
00726 COPY (save, before);
00727 COPY (tmp, save);
00728 check_init (try_clause, tmp);
00729 done_alternative (tmp, &alt);
00730 for ( ; clause != NULL_TREE; clause = TREE_CHAIN (clause))
00731 {
00732 tree catch_clause = TREE_OPERAND (clause, 0);
00733 COPY (tmp, save);
00734 check_init (catch_clause, tmp);
00735 done_alternative (tmp, &alt);
00736 }
00737 if (tmp != buf)
00738 {
00739 FREE_WORDS (tmp);
00740 }
00741 END_ALTERNATIVES (before, alt);
00742 }
00743 return;
00744
00745 case TRY_FINALLY_EXPR:
00746 {
00747 DECLARE_BUFFERS(tmp, 1);
00748 COPY (tmp, before);
00749 check_init (TREE_OPERAND (exp, 0), before);
00750 check_init (TREE_OPERAND (exp, 1), tmp);
00751 UNION (before, before, tmp);
00752 RELEASE_BUFFERS(tmp);
00753 }
00754 return;
00755
00756 case RETURN_EXPR:
00757 case THROW_EXPR:
00758 if (TREE_OPERAND (exp, 0))
00759 check_init (TREE_OPERAND (exp, 0), before);
00760 goto never_continues;
00761
00762 case ERROR_MARK:
00763 never_continues:
00764 SET_ALL (before);
00765 return;
00766
00767 case COND_EXPR:
00768 case TRUTH_ANDIF_EXPR:
00769 case TRUTH_ORIF_EXPR:
00770 {
00771 DECLARE_BUFFERS(when_true, 2);
00772 words when_false = when_true + num_current_words;
00773 check_bool_init (exp, before, when_false, when_true);
00774 INTERSECT (before, when_false, when_true);
00775 RELEASE_BUFFERS(when_true);
00776 }
00777 break;
00778
00779 case NOP_EXPR:
00780 if (exp == empty_stmt_node)
00781 break;
00782
00783 case UNARY_PLUS_EXPR:
00784 case NEGATE_EXPR:
00785 case TRUTH_AND_EXPR:
00786 case TRUTH_OR_EXPR:
00787 case TRUTH_XOR_EXPR:
00788 case TRUTH_NOT_EXPR:
00789 case BIT_NOT_EXPR:
00790 case CONVERT_EXPR:
00791 case BIT_FIELD_REF:
00792 case FLOAT_EXPR:
00793 case FIX_TRUNC_EXPR:
00794 case INDIRECT_REF:
00795 case ADDR_EXPR:
00796 case NON_LVALUE_EXPR:
00797 case INSTANCEOF_EXPR:
00798 case FIX_CEIL_EXPR:
00799 case FIX_FLOOR_EXPR:
00800 case FIX_ROUND_EXPR:
00801 case ABS_EXPR:
00802 case FFS_EXPR:
00803
00804 exp = TREE_OPERAND (exp, 0);
00805 goto again;
00806
00807 case PREDECREMENT_EXPR:
00808 case PREINCREMENT_EXPR:
00809 case POSTDECREMENT_EXPR:
00810 case POSTINCREMENT_EXPR:
00811 tmp = get_variable_decl (TREE_OPERAND (exp, 0));
00812 if (tmp != NULL_TREE && DECL_FINAL (tmp))
00813 final_assign_error (DECL_NAME (tmp));
00814
00815
00816 exp = TREE_OPERAND (exp, 0);
00817 goto again;
00818
00819 case SAVE_EXPR:
00820 if (IS_INIT_CHECKED (exp))
00821 return;
00822 IS_INIT_CHECKED (exp) = 1;
00823 exp = TREE_OPERAND (exp, 0);
00824 goto again;
00825
00826 case COMPOUND_EXPR:
00827 case PLUS_EXPR:
00828 case MINUS_EXPR:
00829 case MULT_EXPR:
00830 case TRUNC_DIV_EXPR:
00831 case TRUNC_MOD_EXPR:
00832 case RDIV_EXPR:
00833 case LSHIFT_EXPR:
00834 case RSHIFT_EXPR:
00835 case URSHIFT_EXPR:
00836 case BIT_AND_EXPR:
00837 case BIT_XOR_EXPR:
00838 case BIT_IOR_EXPR:
00839 case EQ_EXPR:
00840 case NE_EXPR:
00841 case GT_EXPR:
00842 case GE_EXPR:
00843 case LT_EXPR:
00844 case LE_EXPR:
00845 case MAX_EXPR:
00846 case MIN_EXPR:
00847 case ARRAY_REF:
00848 case LROTATE_EXPR:
00849 case RROTATE_EXPR:
00850 case CEIL_DIV_EXPR:
00851 case FLOOR_DIV_EXPR:
00852 case ROUND_DIV_EXPR:
00853 case CEIL_MOD_EXPR:
00854 case FLOOR_MOD_EXPR:
00855 case ROUND_MOD_EXPR:
00856 case EXACT_DIV_EXPR:
00857 binop:
00858 check_init (TREE_OPERAND (exp, 0), before);
00859
00860 exp = TREE_OPERAND (exp, 1);
00861 goto again;
00862
00863 case RESULT_DECL:
00864 case FUNCTION_DECL:
00865 case INTEGER_CST:
00866 case REAL_CST:
00867 case STRING_CST:
00868 case JAVA_EXC_OBJ_EXPR:
00869 break;
00870
00871 case NEW_CLASS_EXPR:
00872 case CALL_EXPR:
00873 {
00874 tree func = TREE_OPERAND (exp, 0);
00875 tree x = TREE_OPERAND (exp, 1);
00876 if (TREE_CODE (func) == ADDR_EXPR)
00877 func = TREE_OPERAND (func, 0);
00878 check_init (func, before);
00879
00880 for ( ; x != NULL_TREE; x = TREE_CHAIN (x))
00881 check_init (TREE_VALUE (x), before);
00882 if (func == throw_node)
00883 goto never_continues;
00884 }
00885 break;
00886
00887 case NEW_ARRAY_INIT:
00888 {
00889 tree x = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
00890 for ( ; x != NULL_TREE; x = TREE_CHAIN (x))
00891 check_init (TREE_VALUE (x), before);
00892 }
00893 break;
00894
00895 case EXPR_WITH_FILE_LOCATION:
00896 {
00897 const char *saved_input_filename = input_filename;
00898 tree saved_wfl = wfl;
00899 tree body = EXPR_WFL_NODE (exp);
00900 int saved_lineno = lineno;
00901 if (body == empty_stmt_node)
00902 break;
00903 wfl = exp;
00904 input_filename = EXPR_WFL_FILENAME (exp);
00905 lineno = EXPR_WFL_LINENO (exp);
00906 check_init (body, before);
00907 input_filename = saved_input_filename;
00908 lineno = saved_lineno;
00909 wfl = saved_wfl;
00910 }
00911 break;
00912
00913 default:
00914 internal_error
00915 ("internal error in check-init: tree code not implemented: %s",
00916 tree_code_name [(int) TREE_CODE (exp)]);
00917 }
00918 }
00919
00920 void
00921 check_for_initialization (body, mdecl)
00922 tree body, mdecl;
00923 {
00924 tree decl;
00925 word buf[2];
00926 words before = buf;
00927 tree owner = DECL_CONTEXT (mdecl);
00928 int is_static_method = METHOD_STATIC (mdecl);
00929
00930 int is_finit_method = DECL_FINIT_P (mdecl) || DECL_INSTINIT_P (mdecl);
00931 int is_init_method
00932 = (is_finit_method || DECL_CLINIT_P (mdecl)
00933 || (DECL_INIT_P (mdecl) && ! DECL_INIT_CALLS_THIS (mdecl)));
00934
00935 start_current_locals = num_current_locals = 0;
00936 num_current_words = 2;
00937
00938 if (is_init_method)
00939 {
00940 int words_needed, i;
00941 for (decl = TYPE_FIELDS (owner);
00942 decl != NULL_TREE; decl = TREE_CHAIN (decl))
00943 {
00944 if (DECL_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
00945 {
00946 if (DECL_FIELD_FINAL_IUD (decl))
00947 DECL_BIT_INDEX (decl) = -1;
00948 else
00949 DECL_BIT_INDEX (decl) = num_current_locals++;
00950 }
00951 }
00952 words_needed = WORDS_NEEDED (2 * num_current_locals);
00953 if (words_needed > 2)
00954 {
00955 num_current_words = words_needed;
00956 before = ALLOC_WORDS(words_needed);
00957 }
00958 i = 0;
00959 for (decl = TYPE_FIELDS (owner);
00960 decl != NULL_TREE; decl = TREE_CHAIN (decl))
00961 {
00962 if (FIELD_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
00963 {
00964 if (! DECL_FIELD_FINAL_IUD (decl))
00965 {
00966 CLEAR_ASSIGNED (before, i);
00967 SET_UNASSIGNED (before, i);
00968 i++;
00969 }
00970 }
00971 }
00972
00973 }
00974
00975 check_init (body, before);
00976
00977 if (is_init_method)
00978 {
00979 for (decl = TYPE_FIELDS (owner);
00980 decl != NULL_TREE; decl = TREE_CHAIN (decl))
00981 {
00982 if (FIELD_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
00983 {
00984 int index = DECL_BIT_INDEX (decl);
00985 if (index >= 0 && ! ASSIGNED_P (before, index))
00986 {
00987 if (! is_finit_method)
00988 error_with_decl (decl, "final field '%s' may not have been initialized");
00989 }
00990 else if (is_finit_method)
00991 DECL_FIELD_FINAL_IUD (decl) = 1;
00992
00993
00994
00995 DECL_BIT_INDEX (decl) = -1;
00996 }
00997 }
00998 }
00999
01000 start_current_locals = num_current_locals = 0;
01001 }
01002
01003
01004
01005
01006
01007 bool
01008 attach_initialized_static_class (entry, ptr)
01009 struct hash_entry *entry;
01010 PTR ptr;
01011 {
01012 struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
01013 tree fndecl = DECL_CONTEXT (ite->init_test_decl);
01014 int index = DECL_BIT_INDEX (ite->init_test_decl);
01015
01016
01017
01018
01019 if (fndecl && METHOD_STATIC (fndecl)
01020 && (DECL_INITIAL (ite->init_test_decl) == boolean_true_node
01021 || (index >= 0 && ASSIGNED_P (((word *) ptr), index))))
01022 hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
01023 entry->key, TRUE, NULL);
01024 return true;
01025 }