This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] Java: Definite [Un]Assignment Issues


Hi,

    This patch represents my attempt at fixing some of the
problems we have with definite [un]assignment in Java (JLS 2
Chapter 16).

These problems are only exposed by the Jacks testsuite.

Background:
-----------
GCJ started showing 30 XPASSes and 5 FAILs with Jacks after the tree-ssa
merge. This was because we were no longer throwing away an if-else with
a constant boolean condition. I started off with an attempt to fix these
FAILs, but have stopped for the moment at the state represented by this
patch.

Summary:
--------
Before my patch there were 30 XPASSes and 5 FAILs with Jacks.

After my patch there are 47 XPASSes and 5 FAILs with Jacks.

Diagnostics:
------------
The remaining FAILs are:

  16.2.9-definite-unassign-pass-3
  16.2.10-definite-unassign-pass-3
  16.2.11-definite-unassign-pass-3
  16.2.8-final-3
  16.2.8-final-4

The first three - 16.2.{9,10,11}-definite-unassign-pass-3 - existed before
my patch and represent our decision to simplify the handling of loops w.r.t.
definite [un]assignment. See the comment for the "case LOOP_EXPR" in
check_init() in java/check-init.c for reference. Unless we want to change
that decision, I recommend that we simply mark these as expected "failures".

The next two represent failures with final variables inside switch
statements that I simply did not have the enthusiasm or energy to
pursue. :-(

Details:
--------
The following are the needed details on the patch in the order
of appearance of the associated changes:

a. Surprisingly for me, we were not at all marking "blank final" local
   variables that represent the entities for which the whole "definite
   unassignment" brouhaha in JLS 2 Chapter 16 is about!

   I define DECL_LOCAL_FINAL_IUD in java-tree.h that is similar to - in fact
   the same as - DECL_FIELD_FINAL_IUD, that I use to mark final
   local variables that are initialised in their declaration. This is
   being done in declare_local_variables() in parse.y in my patch.

b. With the above in place, check_final_reassigned() in check-init.c had
   to be changed to give an error if an assignment to a final variable is
   done when it is either:

     i) "blank final" and not definitely unassigned, or,
    ii) initialised final and reassigned

   in accordance with the JLS.

c. JLS 2 16.1.7 clarifies how boolean assignment expressions should behave
   when true/false. We were not honouring that.

d. We have a minor optimisation that removes initialised local variables to
   reduce the length of the bitstrings maintained in memory. However, we
   were not taking care to remove only non-final local variables, as these
   need to be tracked to check for reassignments.

Checked on i686-pc-linux-gnu with no libjava testsuite regressions and
Jacks affected as summarised above.

Questions:
----------
1. OK for mainline?

2. If "Yes" for the above, OK to update
   "libjava/testsuite/libjava.jacks/jacks.xfail" appropriately?

Thanks,
Ranjit.

Index: ChangeLog
from  Ranjit Mathew  <rmathew@hotmail.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.
	(check_init): Perform initialised-variable-removing-optimisation
	only on non-final local variables.

Index: java-tree.h
===================================================================
--- java-tree.h	2004-05-23 17:33:35.000000000 +0530
+++ java-tree.h	2004-05-23 17:36:45.000000000 +0530
@@ -902,8 +902,8 @@ union lang_tree_node
 /* 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)
@@ -911,6 +911,8 @@ union lang_tree_node
 #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. */
Index: parse.y
===================================================================
--- parse.y	2004-05-23 15:59:32.000000000 +0530
+++ parse.y	2004-05-23 17:37:35.000000000 +0530
@@ -7375,6 +7375,13 @@ declare_local_variables (int modifier, t
       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)
 	{
Index: check-init.c
===================================================================
--- check-init.c	2004-05-21 21:14:10.000000000 +0530
+++ check-init.c	2004-05-23 20:17:03.000000000 +0530
@@ -210,7 +210,8 @@ check_final_reassigned (tree decl, words
      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) && ! UNASSIGNED_P (before, index))
+	  || (DECL_LOCAL_FINAL_IUD (decl) && ASSIGNED_P (before, index))))
     {
       final_assign_error (DECL_NAME (decl));
     }
@@ -346,6 +347,8 @@ check_bool_init (tree exp, words before,
 	    check_bool_init (TREE_OPERAND (exp, 1), before,
 			     when_false, when_true);
 	    check_final_reassigned (tmp, before);
+	    INTERSECT (when_false, when_false, when_true);
+	    COPY (when_true, when_false);
 	    index = DECL_BIT_INDEX (tmp);
 	    if (index >= 0)
 	      {
@@ -531,6 +534,7 @@ check_init (tree exp, words 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)
 	    {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]