java compile failure

Alexandre Petit-Bianco apbianco@cygnus.com
Sun Aug 12 17:31:00 GMT 2001


aking@dreammechanics.com writes:
> I've been able to shrink it down to the minimum code required to
> generate the compile error:

This was helpful. I added your testcase to our testsuite.
> I'm using the cvs version from Sunday night, with the
> "gcc-3_0-branch' tag.

This probably will never be fixed in 3.0.
I'm about to finish testing what follow, and I'll check it into the
trunk.
./A
libjava/testsuite:
2001年08月12日 Alexandre Petit-Bianco <apbianco@redhat.com>
	
	* libjava.lang/Matrix4f.java: New file.
	* libjava.lang/Matrix4f.out: New file.
Index: libjava.lang/Matrix4f.java
===================================================================
RCS file: Matrix4f.java
diff -N Matrix4f.java
--- /dev/null	Tue May 5 13:32:27 1998
+++ Matrix4f.java	Sun Aug 12 17:22:48 2001
@@ -0,0 +1,129 @@
+/*
+* Instance initializers are now turned into a new function instinit$ and called
+* from the ctor. SAVE_EXPRs can't be easily shared.
+*
+* Contributed by Adam King <aking@dreammechanics.com>
+*
+*/
+
+public class Matrix4f
+{
+ public float m00;
+ public float m01;
+ public float m02;
+ public float m03;
+ public float m10;
+ public float m11;
+ public float m12;
+ public float m13;
+ public float m20;
+ public float m21;
+ public float m22;
+ public float m23;
+ public float m30;
+ public float m31;
+ public float m32;
+ public float m33;
+
+ private float scale;
+
+ static boolean initialized;
+ static Matrix4f xmat;
+ static Matrix4f ymat;
+ static Matrix4f zmat;
+ static Matrix4f tempMatrix1;
+ static Matrix4f tempMatrix2;
+
+ {
+ if( !initialized )
+ {
+		 System.out.println ("not initialized");
+ initialized = true;
+ xmat = new Matrix4f();
+ ymat = new Matrix4f();
+ zmat = new Matrix4f();
+ tempMatrix1 = new Matrix4f();
+ tempMatrix2 = new Matrix4f();
+ }
+		else { System.out.println ("initialized"); }
+		 
+ }
+
+ public Matrix4f()
+ {
+ m00 = 1;
+ m01 = 0;
+ m02 = 0;
+ m03 = 0;
+ m10 = 0;
+ m11 = 1;
+ m12 = 0;
+ m13 = 0;
+ m20 = 0;
+ m21 = 0;
+ m22 = 1;
+ m23 = 0;
+ m30 = 0;
+ m31 = 0;
+ m32 = 0;
+ m33 = 1;
+ }
+
+ public Matrix4f( float v[] )
+ {
+ m00 = v[0];
+ m01 = v[1];
+ m02 = v[2];
+ m03 = v[3];
+ m10 = v[4];
+ m11 = v[5];
+ m12 = v[6];
+ m13 = v[7];
+ m20 = v[8];
+ m21 = v[9];
+ m22 = v[10];
+ m23 = v[11];
+ m30 = v[12];
+ m31 = v[13];
+ m32 = v[14];
+ m33 = v[15];
+ }
+
+ public Matrix4f( float m00, float m01, float m02, float m03,
+ float m10, float m11, float m12, float m13, 
+ float m20, float m21, float m22, float m23, 
+ float m30, float m31, float m32, float m33 )
+ {
+ this.m00 = m00;
+ this.m01 = m01;
+ this.m02 = m02;
+ this.m03 = m03;
+ this.m10 = m10;
+ this.m11 = m11;
+ this.m12 = m12;
+ this.m13 = m13;
+ this.m20 = m20;
+ this.m21 = m21;
+ this.m22 = m22;
+ this.m23 = m23;
+ this.m30 = m30;
+ this.m31 = m31;
+ this.m32 = m32;
+ this.m33 = m33;
+ }
+
+ public static void main( String[] args )
+ {
+	 System.out.println( "Test main..." );
+	 new Matrix4f ();
+	 new Matrix4f (0,0,0,0,
+			 0,0,0,0,
+			 0,0,0,0,
+			 0,0,0,0);
+	 new Matrix4f (new float [] {0,0,0,0,
+					0,0,0,0,
+					0,0,0,0,
+					0,0,0,0});
+ }
+}
+
Index: libjava.lang/Matrix4f.out
===================================================================
RCS file: Matrix4f.out
diff -N Matrix4f.out
--- /dev/null	Tue May 5 13:32:27 1998
+++ Matrix4f.out	Sun Aug 12 17:22:48 2001
@@ -0,0 +1,9 @@
+Test main...
+not initialized
+initialized
+initialized
+initialized
+initialized
+initialized
+initialized
+initialized
gcc/java:
2001年08月12日 Alexandre Petit-Bianco <apbianco@redhat.com>
	* decl.c (init_decl_processing): exception_type_node,
	class_not_found_type_node, and no_class_def_found_type_node
	initialized. predef_filenames augmented accordingly.
	instinit_identifier_node initialized.
	* java-tree.def (INSTANCE_INITIALIZERS_EXPR): Entry removed.
	* java-tree.h (enum java_tree_index): New entries
	JTI_EXCEPTION_TYPE_NODE, JTI_CLASS_NOT_FOUND_TYPE_NODE,
	JTI_NO_CLASS_DEF_FOUND_TYPE_NODE, JTI_INSTINIT_IDENTIFIER_NODE.
	(exception_type_node): New macro.
	(class_not_found_type_node): Likewise.
	(no_class_def_found_type_node): Likewise.
	(instinit_identifier_node): Likewise.
	(PREDEF_FILENAMES_SIZE): Adjusted.
	(TYPE_HAS_FINAL_VARIABLE): Fixed typo.
	(struct lang_type): Fixed typo in bitfield name.
	(DECL_INSTINIT_P): New macro.
	(ID_INSTINIT_P): Likewise.
	* jcf-write.h (generate_classfile): instinit$ bears the Synthetic
	attribute.
	* parse.y (encapsulate_with_try_catch): New function.
	(generate_instinit): Likewise.
	(build_instinit_invocation): Likewise.
	(add_instance_initializer): Deleted.
	(build_instance_initializer): Likewise.
	(in_instance_initializer): Likewise.
	(check_method_redefinition): instinit$ not to be verified.
	(java_complete_expand_methods): New local instinit. Generate instinit$
	(build_dot_class_method): Eliminated unnecessary locals. Use
	encapsulate_with_try_catch, removed unnecessary code.
	(fix_constructors): New local iii. Use build_instinit_invocation.
	(patch_method_invocation): Added comment.
	(maybe_use_access_method): Don't consider instinit$.
	(find_applicable_accessible_methods_list): Shorten the search for
	instinit$ too.
	(java_complete_lhs): case INSTANCE_INITIALIZERS_EXPR removed.
	(patch_return): Use DECL_INSTINIT_P instead of in_instance_initializer.
	(patch_throw_statement): Likewise. Fixed typo.
	
Index: decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/decl.c,v
retrieving revision 1.105
diff -u -p -r1.105 decl.c
--- decl.c	2001年08月09日 04:19:11	1.105
+++ decl.c	2001年08月13日 00:23:40
@@ -541,10 +541,16 @@ init_decl_processing ()
 string_ptr_type_node = promote_type (string_type_node);
 class_type_node = lookup_class (get_identifier ("java.lang.Class"));
 throwable_type_node = lookup_class (get_identifier ("java.lang.Throwable"));
+ exception_type_node = lookup_class (get_identifier ("java.lang.Exception"));
 runtime_exception_type_node = 
 lookup_class (get_identifier ("java.lang.RuntimeException"));
 error_exception_type_node = 
 lookup_class (get_identifier ("java.lang.Error"));
+ class_not_found_type_node = 
+ lookup_class (get_identifier ("java.lang.ClassNotFoundException"));
+ no_class_def_found_type_node = 
+ lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
+
 rawdata_ptr_type_node
 = promote_type (lookup_class (get_identifier ("gnu.gcj.RawData")));
 
@@ -557,6 +563,9 @@ init_decl_processing ()
 predef_filenames [4] = get_identifier ("java/lang/String.java");
 predef_filenames [5] = get_identifier ("java/lang/Throwable.java");
 predef_filenames [6] = get_identifier ("gnu/gcj/RawData.java");
+ predef_filenames [7] = get_identifier ("java/lang/Exception");
+ predef_filenames [8] = get_identifier ("java/lang/ClassNotFoundException");
+ predef_filenames [9] = get_identifier ("java/lang/NoClassDefFoundError");
 
 methodtable_type = make_node (RECORD_TYPE);
 layout_type (methodtable_type);
@@ -572,6 +581,7 @@ init_decl_processing ()
 /* The new `finit$' special method identifier. This one is now
 generated in place of `$finit$'. */
 finit_identifier_node = get_identifier ("finit$");
+ instinit_identifier_node = get_identifier ("instinit$");
 void_signature_node = get_identifier ("()V");
 length_identifier_node = get_identifier ("length");
 this_identifier_node = get_identifier ("this");
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.114
diff -u -p -r1.114 expr.c
--- expr.c	2001年08月09日 04:19:12	1.114
+++ expr.c	2001年08月13日 00:23:42
@@ -2505,8 +2505,8 @@ java_lang_expand_expr (exp, target, tmod
 	 }
 	 expand_expr (body, const0_rtx, VOIDmode, 0);
 	 emit_queue ();
-	 poplevel (1, 1, 0);
 	 expand_end_bindings (getdecls (), 1, 0);
+	 poplevel (1, 1, 0);
 	 return const0_rtx;
 	}
 return const0_rtx;
Index: java-tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.def,v
retrieving revision 1.16
diff -u -p -r1.16 java-tree.def
--- java-tree.def	2001年05月13日 04:59:32	1.16
+++ java-tree.def	2001年08月13日 00:23:42
@@ -88,12 +88,6 @@ DEFTREECODE (NEW_ARRAY_INIT, "new_array_
 reference from. */
 DEFTREECODE (CLASS_LITERAL, "class_literal", '1', 1)
 
-/* Instance initializer.
- Operand 0 contains the intance initializer statement. This tree node
- is used for context detection, so that special rules can be
- enforced. */
-DEFTREECODE (INSTANCE_INITIALIZERS_EXPR, "instance_initializers_expr", '1', 1)
-
 /* The Java object within the exception object from the runtime. */
 DEFTREECODE (JAVA_EXC_OBJ_EXPR, "java_exc_obj_expr", 'e', 0)
 
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.118
diff -u -p -r1.118 java-tree.h
--- java-tree.h	2001年08月09日 04:19:12	1.118
+++ java-tree.h	2001年08月13日 00:23:44
@@ -251,9 +251,12 @@ enum java_tree_index
 JTI_STRING_TYPE_NODE,
 JTI_STRING_PTR_TYPE_NODE,
 JTI_THROWABLE_TYPE_NODE,
+ JTI_EXCEPTION_TYPE_NODE,
 JTI_RUNTIME_EXCEPTION_TYPE_NODE,
 JTI_ERROR_EXCEPTION_TYPE_NODE,
 JTI_RAWDATA_PTR_TYPE_NODE,
+ JTI_CLASS_NOT_FOUND_TYPE_NODE,
+ JTI_NO_CLASS_DEF_FOUND_TYPE_NODE,
 
 JTI_BYTE_ARRAY_TYPE_NODE,
 JTI_SHORT_ARRAY_TYPE_NODE,
@@ -278,6 +281,7 @@ enum java_tree_index
 JTI_INIT_IDENTIFIER_NODE, 
 JTI_CLINIT_IDENTIFIER_NODE, 
 JTI_FINIT_IDENTIFIER_NODE, 
+ JTI_INSTINIT_IDENTIFIER_NODE,
 JTI_FINIT_LEG_IDENTIFIER_NODE, 
 JTI_VOID_SIGNATURE_NODE, 
 JTI_LENGTH_IDENTIFIER_NODE, 
@@ -408,12 +412,18 @@ extern tree java_global_trees[JTI_MAX];
 java_global_trees[JTI_STRING_PTR_TYPE_NODE]
 #define throwable_type_node \
 java_global_trees[JTI_THROWABLE_TYPE_NODE]
+#define exception_type_node \
+ java_global_trees[JTI_EXCEPTION_TYPE_NODE]
 #define runtime_exception_type_node \
 java_global_trees[JTI_RUNTIME_EXCEPTION_TYPE_NODE]
 #define error_exception_type_node \
 java_global_trees[JTI_ERROR_EXCEPTION_TYPE_NODE]
 #define rawdata_ptr_type_node \
 java_global_trees[JTI_RAWDATA_PTR_TYPE_NODE]
+#define class_not_found_type_node \
+ java_global_trees[JTI_CLASS_NOT_FOUND_TYPE_NODE]
+#define no_class_def_found_type_node \
+ java_global_trees[JTI_NO_CLASS_DEF_FOUND_TYPE_NODE]
 
 #define byte_array_type_node \
 java_global_trees[JTI_BYTE_ARRAY_TYPE_NODE]
@@ -463,6 +473,8 @@ extern tree java_global_trees[JTI_MAX];
 java_global_trees[JTI_FINIT_IDENTIFIER_NODE] /* "finit$" */
 #define finit_leg_identifier_node \
 java_global_trees[JTI_FINIT_LEG_IDENTIFIER_NODE] /* "$finit$" */
+#define instinit_identifier_node \
+ java_global_trees[JTI_INSTINIT_IDENTIFIER_NODE] /* "instinit$" */
 #define void_signature_node \
 java_global_trees[JTI_VOID_SIGNATURE_NODE] /* "()V" */
 #define length_identifier_node \
@@ -598,7 +610,7 @@ extern tree java_global_trees[JTI_MAX];
 #define nativecode_ptr_array_type_node \
 java_global_trees[JTI_NATIVECODE_PTR_ARRAY_TYPE_NODE]
 
-#define PREDEF_FILENAMES_SIZE 7
+#define PREDEF_FILENAMES_SIZE 10
 extern tree predef_filenames[PREDEF_FILENAMES_SIZE];
 
 #define nativecode_ptr_type_node ptr_type_node
@@ -937,7 +949,7 @@ struct lang_decl_var
 #define TYPE_PACKAGE_LIST(T) (TYPE_LANG_SPECIFIC(T)->package_list)
 #define TYPE_PRIVATE_INNER_CLASS(T) (TYPE_LANG_SPECIFIC(T)->pic)
 #define TYPE_PROTECTED_INNER_CLASS(T) (TYPE_LANG_SPECIFIC(T)->poic)
-#define TYPE_HAS_FINAL_VARIABLE(T) (TYPE_LANG_SPECIFIC(T)->afv)
+#define TYPE_HAS_FINAL_VARIABLE(T) (TYPE_LANG_SPECIFIC(T)->hfv)
 
 struct lang_type
 {
@@ -955,7 +967,7 @@ struct lang_type
 tree package_list;		/* List of package names, progressive */
 unsigned pic:1;		/* Private Inner Class. */
 unsigned poic:1;		/* Protected Inner Class. */
- unsigned afv:1;		/* Has final variables */
+ unsigned hfv:1;		/* Has final variables */
 };
 
 #ifdef JAVA_USE_HANDLES
@@ -1197,6 +1209,7 @@ struct rtx_def * java_lang_expand_expr P
 #define DECL_INIT_P(DECL) (ID_INIT_P (DECL_NAME (DECL)))
 #define DECL_FINIT_P(DECL) (ID_FINIT_P (DECL_NAME (DECL)))
 #define DECL_CLINIT_P(DECL) (ID_CLINIT_P (DECL_NAME (DECL)))
+#define DECL_INSTINIT_P(DECL) (ID_INSTINIT_P (DECL_NAME (DECL)))
 
 /* Predicates on method identifiers. Kept close to other macros using
 them */
@@ -1209,6 +1222,7 @@ struct rtx_def * java_lang_expand_expr P
 			 || (ID) == finit_leg_identifier_node)
 #define ID_CLINIT_P(ID) ((ID) == clinit_identifier_node)
 #define ID_CLASSDOLLAR_P(ID) ((ID) == classdollar_identifier_node)
+#define ID_INSTINIT_P(ID) ((ID) == instinit_identifier_node)
 
 /* Access flags etc for a variable/field (a FIELD_DECL): */
 
Index: jcf-write.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-write.c,v
retrieving revision 1.82
diff -u -p -r1.82 jcf-write.c
--- jcf-write.c	2001年08月01日 02:28:42	1.82
+++ jcf-write.c	2001年08月13日 00:23:45
@@ -2935,7 +2935,8 @@ generate_classfile (clas, state)
 i = (body != NULL_TREE) + (DECL_FUNCTION_THROWS (part) != NULL_TREE);
 
 /* Make room for the Synthetic attribute (of zero length.) */
- if (DECL_FINIT_P (part) 
+ if (DECL_FINIT_P (part)
+	 || DECL_INSTINIT_P (part)
 	 || OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (part))
 	 || TYPE_DOT_CLASS (clas) == part)
 	{
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.299
diff -u -p -r1.299 parse.y
--- parse.y	2001年08月09日 04:19:12	1.299
+++ parse.y	2001年08月13日 00:23:54
@@ -221,6 +221,7 @@ static tree string_constant_concatenatio
 static tree build_string_concatenation PARAMS ((tree, tree));
 static tree patch_string_cst PARAMS ((tree));
 static tree patch_string PARAMS ((tree));
+static tree encapsulate_with_try_catch PARAMS ((int, tree, tree, tree));
 static tree build_try_statement PARAMS ((int, tree, tree));
 static tree build_try_finally_statement PARAMS ((int, tree, tree));
 static tree patch_try_statement PARAMS ((tree));
@@ -239,8 +240,8 @@ static tree build_this_super_qualified_i
 static const char *get_printable_method_name PARAMS ((tree));
 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
 static tree generate_finit PARAMS ((tree));
-static void add_instance_initializer PARAMS ((tree));
-static tree build_instance_initializer PARAMS ((tree));
+static tree generate_instinit PARAMS ((tree));
+static tree build_instinit_invocation PARAMS ((tree));
 static void fix_constructors PARAMS ((tree));
 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
 							 tree, int *));
@@ -349,9 +350,6 @@ int do_not_fold;
 /* Cyclic inheritance report, as it can be set by layout_class */
 const char *cyclic_inheritance_report;
 
-/* Tell when we're within an instance initializer */
-static int in_instance_initializer;
-
 /* The current parser context */
 struct parser_ctxt *ctxp;
 
@@ -4363,29 +4361,97 @@ generate_finit (class_type)
 return mdecl;
 }
 
+/* Generate a function to run the instance initialization code. The
+ private method is called `instinit$'. Unless we're dealing with an
+ anonymous class, we determine whether all ctors of CLASS_TYPE
+ declare a checked exception in their `throws' clause in order to
+ see whether it's necessary to encapsulate the instance initializer
+ statements in a try/catch/rethrow sequence. */
+
 static tree
-build_instance_initializer (mdecl)
- tree mdecl;
+generate_instinit (class_type)
+ tree class_type;
 {
- tree compound = NULL_TREE;
- tree stmt_list = TYPE_II_STMT_LIST (DECL_CONTEXT (mdecl));
 tree current;
+ tree compound = NULL_TREE;
+ tree list = TYPE_II_STMT_LIST (class_type);
+ tree parms = tree_cons (this_identifier_node,
+			 build_pointer_type (class_type), end_params_node);
+ tree mdecl = create_artificial_method (class_type, ACC_PRIVATE,
+					 void_type_node,
+					 instinit_identifier_node, parms);
+ bool use_try_catch = true;
+
+ layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
+		 mdecl, NULL_TREE);
+
+ /* We need to encapsulate the block by a try/catch statement to
+ rethrow exceptions that might occur in the instance initializer.
+ We do that only if all ctors of CLASS_TYPE are set to catch a
+ checked exception. This doesn't apply to anonymous classes (since
+ they don't have declared ctors.) */
+ if (ANONYMOUS_CLASS_P (class_type))
+ use_try_catch = false;
+ else 
+ {
+ /* We want to verify that all ctors throw a unchecked exception
+	 so that we can place the block in a try/catch statement. */
+ for (current = TYPE_METHODS (current_class); current && use_try_catch;
+	 current = TREE_CHAIN (current))
+	{
+	 bool ctu = false;	/* Ctor Throws Unchecked */
+	 if (DECL_CONSTRUCTOR_P (current))
+	 {
+	 tree throws;
+	 for (throws = DECL_FUNCTION_THROWS (current); throws && !ctu;
+		 throws = TREE_CHAIN (throws))
+		if (inherits_from_p (TREE_VALUE (throws), exception_type_node))
+		 ctu = true;
+	 }
+	 /* We find a ctor that is unfit, stop now and avoid try/catch
+ encapsulation. */
+	 if (!ctu && DECL_CONSTRUCTOR_P (current))
+	 use_try_catch = false;
+	}
+ }
 
- for (current = stmt_list; current; current = TREE_CHAIN (current))
+ /* Gather all the statements in a compound and encapsulate in a try/catch
+ sequence if necessary. */
+ for (current = list; current; current = TREE_CHAIN (current))
 compound = add_stmt_to_compound (compound, NULL_TREE, current);
 
- return compound;
+ if (use_try_catch)
+ {
+ compound = encapsulate_with_try_catch (0, exception_type_node, compound, 
+					 build1 (THROW_EXPR, NULL_TREE,
+						 build_wfl_node (wpv_id)));
+ DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
+						 exception_type_node);
+ }
+
+ start_artificial_method_body (mdecl);
+ java_method_add_stmt (mdecl, compound);
+ end_artificial_method_body (mdecl);
+
+ return mdecl;
 }
 
-static void
-add_instance_initializer (mdecl)
- tree mdecl;
+/* FIXME */
+static tree
+build_instinit_invocation (class_type)
+ tree class_type;
 {
- tree compound = build_instance_initializer (mdecl);
+ tree to_return = NULL_TREE;
 
- if (compound)
- java_method_add_stmt (mdecl, build1 (INSTANCE_INITIALIZERS_EXPR,
-					 NULL_TREE, compound));
+ if (TYPE_II_STMT_LIST (class_type))
+ {
+ tree parm = build_tree_list (NULL_TREE,
+				 build_wfl_node (this_identifier_node));
+ to_return =
+	build_method_invocation (build_wfl_node (instinit_identifier_node),
+				 parm);
+ }
+ return to_return;
 }
 
 /* Shared accros method_declarator and method_header to remember the
@@ -5920,8 +5986,9 @@ check_method_redefinition (class, method
 {
 tree redef, sig;
 
- /* There's no need to verify <clinit> and finit$ */
- if (DECL_CLINIT_P (method) || DECL_FINIT_P (method))
+ /* There's no need to verify <clinit> and finit$ and instinit$ */
+ if (DECL_CLINIT_P (method)
+ || DECL_FINIT_P (method) || DECL_INSTINIT_P (method))
 return 0;
 
 sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
@@ -7460,7 +7527,7 @@ static void
 java_complete_expand_methods (class_decl)
 tree class_decl;
 {
- tree clinit, finit, decl, first_decl;
+ tree clinit, finit, instinit, decl, first_decl;
 
 current_class = TREE_TYPE (class_decl);
 
@@ -7482,7 +7549,7 @@ java_complete_expand_methods (class_decl
 first_decl = TYPE_METHODS (current_class);
 clinit = maybe_generate_pre_expand_clinit (current_class);
 
- /* Then generate finit$ (if we need to) because constructor will
+ /* Then generate finit$ (if we need to) because constructors will
 try to use it.*/
 if (TYPE_FINIT_STMT_LIST (current_class))
 {
@@ -7490,6 +7557,14 @@ java_complete_expand_methods (class_decl
 java_complete_expand_method (finit);
 }
 
+ /* Then generate instinit$ (if we need to) because constructors will
+ try to use it. */
+ if (TYPE_II_STMT_LIST (current_class))
+ {
+ instinit = generate_instinit (current_class);
+ java_complete_expand_method (instinit);
+ }
+
 /* Now do the constructors */
 for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
 {
@@ -8498,9 +8573,7 @@ build_dot_class_method (class)
 #define BWF(S) build_wfl_node (get_identifier ((S)))
 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
 tree args, tmp, saved_current_function_decl, mdecl;
- tree stmt, throw_stmt, catch, catch_block, try_block;
- tree catch_clause_param;
- tree class_not_found_exception, no_class_def_found_error;
+ tree stmt, throw_stmt;
 
 static tree get_message_wfl, type_parm_wfl;
 
@@ -8520,33 +8593,24 @@ build_dot_class_method (class)
 /* Build the qualified name java.lang.Class.forName */
 tmp = MQN (MQN (MQN (BWF ("java"), 
 		 BWF ("lang")), BWF ("Class")), BWF ("forName"));
-
- /* For things we have to catch and throw */
- class_not_found_exception = 
- lookup_class (get_identifier ("java.lang.ClassNotFoundException"));
- no_class_def_found_error = 
- lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
- load_class (class_not_found_exception, 1);
- load_class (no_class_def_found_error, 1);
-
+ load_class (class_not_found_type_node, 1);
+ load_class (no_class_def_found_type_node, 1);
+ 
 /* Create the "class$" function */
 mdecl = create_artificial_method (class, ACC_STATIC, 
 				 build_pointer_type (class_type_node),
 				 classdollar_identifier_node, args);
- DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
-						 no_class_def_found_error);
- 
+ DECL_FUNCTION_THROWS (mdecl) = 
+ build_tree_list (NULL_TREE, no_class_def_found_type_node);
+
 /* We start by building the try block. We need to build:
 return (java.lang.Class.forName (type)); */
 stmt = build_method_invocation (tmp, 
 				 build_tree_list (NULL_TREE, type_parm_wfl));
 stmt = build_return (0, stmt);
- /* Put it in a block. That's the try block */
- try_block = build_expr_block (stmt, NULL_TREE);
 
 /* Now onto the catch block. We start by building the expression
- throwing a new exception: 
- throw new NoClassDefFoundError (_.getMessage); */
+ throwing a new exception: throw new NoClassDefFoundError (_.getMessage) */
 throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
 				 get_message_wfl, 0);
 throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
@@ -8559,27 +8623,9 @@ build_dot_class_method (class)
 /* Build the throw, (it's too early to use BUILD_THROW) */
 throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
 
- /* Build the catch block to encapsulate all this. We begin by
- building an decl for the catch clause parameter and link it to
- newly created block, the catch block. */
- catch_clause_param = 
- build_decl (VAR_DECL, wpv_id, 
-		build_pointer_type (class_not_found_exception));
- catch_block = build_expr_block (NULL_TREE, catch_clause_param);
- 
- /* We initialize the variable with the exception handler. */
- catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
-		 build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
- add_stmt_to_block (catch_block, NULL_TREE, catch);
-
- /* We add the statement throwing the new exception */
- add_stmt_to_block (catch_block, NULL_TREE, throw_stmt);
-
- /* Build a catch expression for all this */
- catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
-
- /* Build the try/catch sequence */
- stmt = build_try_statement (0, try_block, catch_block);
+ /* Encapsulate STMT in a try block. The catch clause executes THROW_STMT */
+ stmt = encapsulate_with_try_catch (0, class_not_found_type_node,
+				 stmt, throw_stmt);
 
 fix_method_argument_names (args, mdecl);
 layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
@@ -8620,6 +8666,7 @@ static void
 fix_constructors (mdecl)
 tree mdecl;
 {
+ tree iii;			/* Instance Initializer Invocation */
 tree body = DECL_FUNCTION_BODY (mdecl);
 tree thisn_assign, compound = NULL_TREE;
 tree class_type = DECL_CONTEXT (mdecl);
@@ -8661,9 +8708,9 @@ fix_constructors (mdecl)
 	 of that. */
 java_method_add_stmt (mdecl, build_super_invocation (mdecl));
 
- /* Insert the instance initializer block right here, after the
- super invocation. */
- add_instance_initializer (mdecl);
+ /* FIXME */
+ if ((iii = build_instinit_invocation (class_type)))
+	java_method_add_stmt (mdecl, iii);
 
 end_artificial_method_body (mdecl);
 }
@@ -8674,7 +8721,6 @@ fix_constructors (mdecl)
 int invokes_this = 0;
 tree found_call = NULL_TREE;
 tree main_block = BLOCK_EXPR_BODY (body);
- tree ii;			/* Instance Initializer */
 
 while (body)
 	switch (TREE_CODE (body))
@@ -8717,8 +8763,8 @@ fix_constructors (mdecl)
 	}
 
 /* Insert the instance initializer block right after. */
- if (!invokes_this && (ii = build_instance_initializer (mdecl)))
-	compound = add_stmt_to_compound (compound, NULL_TREE, ii);
+ if (!invokes_this && (iii = build_instinit_invocation (class_type)))
+	compound = add_stmt_to_compound (compound, NULL_TREE, iii);
 
 /* Fix the constructor main block if we're adding extra stmts */
 if (compound)
@@ -10285,6 +10331,8 @@ patch_method_invocation (patch, primary,
 if (ret_decl)
 *ret_decl = list;
 patch = patch_invoke (patch, list, args);
+
+ /* Now is a good time to insert the call to finit$ */
 if (is_super_init && CLASS_HAS_FINIT_P (current_class))
 {
 tree finit_parms, finit_call;
@@ -10346,7 +10394,8 @@ maybe_use_access_method (is_super_init, 
 if (is_super_init 
 || DECL_CONTEXT (md) == current_class
 || !PURE_INNER_CLASS_TYPE_P (current_class) 
- || DECL_FINIT_P (md))
+ || DECL_FINIT_P (md)
+ || DECL_INSTINIT_P (md))
 return 0;
 
 /* If we're calling a method found in an enclosing class, generate
@@ -10717,10 +10766,10 @@ find_applicable_accessible_methods_list 
 search_applicable_methods_list (lc, TYPE_METHODS (class), 
 				 name, arglist, &list, &all_list);
 
- /* When looking finit$ or class,ドル we turn LC to 1 so that we
-	 only search in class. Note that we should have found
+ /* When looking finit,ドル class$ or instinit,ドル we turn LC to 1 so
+	 that we only search in class. Note that we should have found
 	 something at this point. */
- if (ID_FINIT_P (name) || ID_CLASSDOLLAR_P (name))
+ if (ID_FINIT_P (name) || ID_CLASSDOLLAR_P (name) || ID_INSTINIT_P (name))
 	{
 	 lc = 1;
 	 if (!list)
@@ -12001,16 +12050,6 @@ java_complete_lhs (node)
 	return error_mark_node;
 break;
 
- case INSTANCE_INITIALIZERS_EXPR:
- in_instance_initializer++;
- node = java_complete_tree (TREE_OPERAND (node, 0));
- in_instance_initializer--;
- if (node != error_mark_node)
-	TREE_TYPE (node) = void_type_node;
- else
-	return error_mark_node;
- break;
-
 default:
 CAN_COMPLETE_NORMALLY (node) = 1;
 /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
@@ -14709,12 +14748,12 @@ patch_return (node)
 if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
 error_found = 2;
 
- if (in_instance_initializer)
+ if (DECL_INSTINIT_P (current_function_decl))
 error_found = 1;
 
 if (error_found)
 {
- if (in_instance_initializer)
+ if (DECL_INSTINIT_P (current_function_decl))
 	parse_error_context (wfl_operator,
 			 "`return' inside instance initializer");
 	
@@ -15234,6 +15273,39 @@ patch_switch_statement (node)
 
 /* 14.18 The try/catch statements */
 
+/* Encapsulate TRY_STMTS' in a try catch sequence. The catch clause
+ catches TYPE and executes CATCH_STMTS. */
+
+static tree
+encapsulate_with_try_catch (location, type, try_stmts, catch_stmts)
+ int location;
+ tree type, try_stmts, catch_stmts;
+{
+ tree try_block, catch_clause_param, catch_block, catch;
+
+ /* First build a try block */
+ try_block = build_expr_block (try_stmts, NULL_TREE);
+
+ /* Build a catch block: we need a catch clause parameter */
+ catch_clause_param = build_decl (VAR_DECL, 
+				 wpv_id, build_pointer_type (type));
+ /* And a block */
+ catch_block = build_expr_block (NULL_TREE, catch_clause_param);
+ 
+ /* Initialize the variable and store in the block */
+ catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
+		 build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
+ add_stmt_to_block (catch_block, NULL_TREE, catch);
+
+ /* Add the catch statements */
+ add_stmt_to_block (catch_block, NULL_TREE, catch_stmts);
+
+ /* Now we can build a CATCH_EXPR */
+ catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
+
+ return build_try_statement (location, try_block, catch_block);
+}
+
 static tree
 build_try_statement (location, try_block, catches)
 int location;
@@ -15468,12 +15540,13 @@ patch_throw_statement (node, wfl_op1)
 unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
 
 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
- /* An instance can't throw a checked excetion unless that exception
+ /* An instance can't throw a checked exception unless that exception
 is explicitely declared in the `throws' clause of each
 constructor. This doesn't apply to anonymous classes, since they
 don't have declared constructors. */
 if (!unchecked_ok 
- && in_instance_initializer && !ANONYMOUS_CLASS_P (current_class))
+ && DECL_INSTINIT_P (current_function_decl)
+ && !ANONYMOUS_CLASS_P (current_class))
 {
 tree current;
 for (current = TYPE_METHODS (current_class); current; 


More information about the Java mailing list

AltStyle によって変換されたページ (->オリジナル) /