+2004-05-29 Ranjit Mathew <rmathew@hotmail.com>
+ Per Bothner <per@bothner.com>
+
+ * java-tree.h (DECL_LOCAL_FINAL_IUD): New macro to test if a
+ local variable was initialised upon declaration.
+ * parse.y (declare_local_variables): Set DECL_LOCAL_FINAL_IUD if
+ variable was final and initialised upon declaration.
+ * check-init.c (check_final_reassigned): Give error only if a blank
+ final is not definitely unassigned or if an initialised final is
+ reassigned.
+ (check_bool_init): Respect JLS2 16.1.7 requirements for boolean
+ assignment expressions. Remove case MODIFY_EXPR, label do_default.
+ (check_init): Perform initialised-variable-removing-optimisation
+ only on non-final local variables.
+
2004-05-28 Bryce McKinlay <mckinlay@redhat.com>
* jcf-write.c (generate_bytecode_conditional): Handle binops
assigned must be reported as errors */
if (DECL_FINAL (decl) && index != -2
&& (index < loop_current_locals /* I.e. -1, or outside current loop. */
- || ! UNASSIGNED_P (before, index)))
+ || (DECL_LOCAL_FINAL_IUD (decl) ? ASSIGNED_P (before, index)
+ : ! UNASSIGNED_P (before, index))))
{
final_assign_error (DECL_NAME (decl));
}
case TRUTH_NOT_EXPR:
check_bool_init (TREE_OPERAND (exp, 0), before, when_true, when_false);
return;
- case MODIFY_EXPR:
- {
- tree tmp = TREE_OPERAND (exp, 0);
- if ((tmp = get_variable_decl (tmp)) != NULL_TREE)
- {
- int index;
- check_bool_init (TREE_OPERAND (exp, 1), before,
- when_false, when_true);
- check_final_reassigned (tmp, before);
- index = DECL_BIT_INDEX (tmp);
- if (index >= 0)
- {
- SET_ASSIGNED (when_false, index);
- SET_ASSIGNED (when_true, index);
- CLEAR_UNASSIGNED (when_false, index);
- CLEAR_UNASSIGNED (when_true, index);
- }
- break;
- }
- }
- goto do_default;
case BIT_AND_EXPR:
case BIT_IOR_EXPR:
COPY (when_true, before);
}
break;
+
default:
- do_default:
check_init (exp, before);
COPY (when_false, before);
COPY (when_true, before);
definitely assigned when once we checked the whole
function. */
if (! STATIC_CLASS_INIT_OPT_P () /* FIXME */
+ && ! DECL_FINAL (tmp)
&& index >= start_current_locals
&& index == num_current_locals - 1)
{
/* Safely tests whether FIELD_INNER_ACCESS exists or not. */
#define FIELD_INNER_ACCESS_P(DECL) \
DECL_LANG_SPECIFIC (DECL) && FIELD_INNER_ACCESS (DECL)
-/* True if a final variable was initialized upon its declaration,
- or (if a field) in an initializer. Set after definite assignment. */
+/* True if a final field was initialized upon its declaration
+ or in an initializer. Set after definite assignment. */
#define DECL_FIELD_FINAL_IUD(NODE) (DECL_LANG_SPECIFIC (NODE)->u.v.final_iud)
/* The original WFL of a final variable. */
#define DECL_FIELD_FINAL_WFL(NODE) (DECL_LANG_SPECIFIC(NODE)->u.v.wfl)
#define DECL_OWNER(NODE) (DECL_LANG_SPECIFIC(NODE)->u.v.owner)
/* True if NODE is a local variable final. */
#define LOCAL_FINAL_P(NODE) (DECL_LANG_SPECIFIC (NODE) && DECL_FINAL (NODE))
+/* True if a final local variable was initialized upon its declaration. */
+#define DECL_LOCAL_FINAL_IUD(NODE) (DECL_LANG_SPECIFIC (NODE)->u.v.final_iud)
/* True if NODE is a final field. */
#define FINAL_VARIABLE_P(NODE) (FIELD_FINAL (NODE) && !FIELD_STATIC (NODE))
/* True if NODE is a class final field. */
if (init && java_error_count)
init = NULL_TREE;
+ /* Remember it if this is an initialized-upon-declaration final
+ variable. */
+ if (init && final_p)
+ {
+ DECL_LOCAL_FINAL_IUD (decl) = 1;
+ }
+
/* Add the initialization function to the current function's code */
if (init)
{