check-init.c: New file.

8
	* check-init.c:  New file.  Checks for definite assignment.
Various minor other changes;  see ChangeLog.

From-SVN: r24523
This commit is contained in:
Per Bothner 1999-01-06 09:49:38 -08:00
parent 4ba9a1aa64
commit bc3ca41b49
6 changed files with 647 additions and 476 deletions

View File

@ -175,7 +175,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir)
#
JAVA_OBJS = parse.o class.o decl.o expr.o constants.o lang.o typeck.o \
except.o verify.o zextract.o jcf-io.o jcf-parse.o mangle.o jcf-write.o \
buffer.o jcf-depend.o jcf-path.o
buffer.o check-init.o jcf-depend.o jcf-path.o
JAVA_OBJS_LITE = parse-scan.o jv-scan.o

View File

@ -1765,7 +1765,37 @@ java_lang_expand_expr (exp, target, tmode, modifier)
HOST_WIDE_INT ilength = java_array_type_length (array_type);
tree length = build_int_2 (ilength, 0);
tree init = TREE_OPERAND (exp, 0);
tree array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
tree array_decl;
#if 0
/* Enable this once we can set the vtable field statically. FIXME */
if (TREE_CONSTANT (init) && TREE_STATIC (init)
&& JPRIMITIVE_TYPE_P (element_type))
{
tree temp, value, init_decl;
START_RECORD_CONSTRUCTOR (temp, object_type_node);
PUSH_FIELD_VALUE (temp, "vtable",
null_pointer_node /* FIXME */
);
PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
FINISH_RECORD_CONSTRUCTOR (temp);
START_RECORD_CONSTRUCTOR (value, array_type);
PUSH_SUPER_VALUE (value, temp);
PUSH_FIELD_VALUE (value, "length", length);
PUSH_FIELD_VALUE (value, "data", init);
FINISH_RECORD_CONSTRUCTOR (value);
init_decl = build_decl (VAR_DECL, generate_name (), array_type);
pushdecl_top_level (init_decl);
TREE_STATIC (init_decl) = 1;
DECL_INITIAL (init_decl) = value;
DECL_IGNORED_P (init_decl) = 1;
TREE_READONLY (init_decl) = 1;
make_decl_rtl (init_decl, NULL, 1);
init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
return expand_expr (init, target, tmode, modifier);
}
#endif
array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
expand_decl (array_decl);
tmp = expand_assignment (array_decl,
build_new_array (element_type, length),

View File

@ -520,6 +520,7 @@ extern tree decode_newarray_type PROTO ((int));
extern tree lookup_field PROTO ((tree*, tree));
extern int is_array_type_p PROTO ((tree));
extern HOST_WIDE_INT java_array_type_length PROTO ((tree));
extern int read_class PROTO ((tree));
extern void load_class PROTO ((tree, int));
extern tree lookup_name PROTO ((tree));
@ -833,6 +834,9 @@ extern tree *type_map;
#define FINALLY_EXPR_LABEL(NODE) TREE_OPERAND ((NODE), 0)
#define FINALLY_EXPR_BLOCK(NODE) TREE_OPERAND ((NODE), 1)
#define BLOCK_EXPR_DECLS(NODE) BLOCK_VARS(NODE)
#define BLOCK_EXPR_BODY(NODE) BLOCK_SUBBLOCKS(NODE)
/* Using a CATCH_EXPR node */
#define CATCH_EXPR_GET_EXPR(NODE, V) (V ? LABELED_BLOCK_BODY (NODE) : (NODE))
@ -841,11 +845,12 @@ extern tree *type_map;
(inherits_from_p ((TYPE), runtime_exception_type_node) \
|| inherits_from_p ((TYPE), error_exception_type_node))
extern int java_error_count; \
/* Make the current function where this macro is invoked report error
messages and and return, if any */
#define java_parse_abort_on_error() \
{ \
extern int java_error_count; \
if (java_error_count) \
if (java_error_count > save_error_count) \
return; \
}

View File

@ -449,17 +449,16 @@ DEFUN(jcf_out_of_synch, (jcf),
free (source);
}
/* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
called from the parser, otherwise it's a RECORD_TYPE node. If
VERBOSE is 1, print error message on failure to load a class. */
/* Read a class with the fully qualified-name NAME.
Return 1 iff we read the requested file.
(It is still possible we failed if the file did not
define the class it is supposed to.) */
void
load_class (class_or_name, verbose)
tree class_or_name;
int verbose;
int
read_class (name)
tree name;
{
JCF this_jcf, *jcf;
tree name;
tree save_current_class = current_class;
char *save_input_filename = input_filename;
JCF *save_current_jcf = current_jcf;
@ -467,17 +466,6 @@ load_class (class_or_name, verbose)
if (current_jcf->read_state)
saved_pos = ftell (current_jcf->read_state);
/* class_or_name can be the name of the class we want to load */
if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
name = class_or_name;
/* In some cases, it's a dependency that we process earlier that
we though */
else if (TREE_CODE (class_or_name) == TREE_LIST)
name = TYPE_NAME (TREE_PURPOSE (class_or_name));
/* Or it's a type in the making */
else
name = DECL_NAME (TYPE_NAME (class_or_name));
push_obstacks (&permanent_obstack, &permanent_obstack);
/* Search in current zip first. */
@ -491,19 +479,8 @@ load_class (class_or_name, verbose)
if (find_class (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name),
&this_jcf, saw_java_source) == 0)
{
if (verbose)
{
error ("Cannot find class file for class %s.",
IDENTIFIER_POINTER (name));
TYPE_SIZE (class_or_name) = error_mark_node;
#if 0
/* FIXME: what to do here? */
if (!strcmp (classpath, DEFAULT_CLASS_PATH))
fatal ("giving up");
#endif
pop_obstacks (); /* FIXME: one pop_obstack() per function */
}
return;
pop_obstacks (); /* FIXME: one pop_obstack() per function */
return 0;
}
else
{
@ -528,7 +505,6 @@ load_class (class_or_name, verbose)
if (!current_jcf->seen_in_zip)
JCF_FINISH (current_jcf);
/* DECL_IGNORED_P (TYPE_NAME (class_or_name)) = 1;*/
pop_obstacks ();
current_class = save_current_class;
@ -536,6 +512,47 @@ load_class (class_or_name, verbose)
current_jcf = save_current_jcf;
if (current_jcf->read_state)
fseek (current_jcf->read_state, saved_pos, SEEK_SET);
return 1;
}
/* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
called from the parser, otherwise it's a RECORD_TYPE node. If
VERBOSE is 1, print error message on failure to load a class. */
/* Replace calls to load_class by having callers call read_class directly
- and then perhaps rename read_class to load_class. FIXME */
void
load_class (class_or_name, verbose)
tree class_or_name;
int verbose;
{
tree name;
/* class_or_name can be the name of the class we want to load */
if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
name = class_or_name;
/* In some cases, it's a dependency that we process earlier that
we though */
else if (TREE_CODE (class_or_name) == TREE_LIST)
name = TYPE_NAME (TREE_PURPOSE (class_or_name));
/* Or it's a type in the making */
else
name = DECL_NAME (TYPE_NAME (class_or_name));
if (read_class (name) == 0 && verbose)
{
error ("Cannot find file for class %s.",
IDENTIFIER_POINTER (name));
if (TREE_CODE (class_or_name) == RECORD_TYPE)
TYPE_SIZE (class_or_name) = error_mark_node;
#if 0
/* FIXME: what to do here? */
if (!strcmp (classpath, DEFAULT_CLASS_PATH))
fatal ("giving up");
#endif
return;
}
}
/* Parse a source file when JCF refers to a source file. */
@ -717,12 +734,15 @@ static void
parse_source_file (file)
tree file;
{
int save_error_count = java_error_count;
/* Mark the file as parsed */
HAS_BEEN_ALREADY_PARSED_P (file) = 1;
lang_init_source (1); /* Error msgs have no method prototypes */
java_init_lex (); /* Initialize the parser */
java_parse_abort_on_error ();
java_parse (); /* Parse and build partial tree nodes. */
java_parse_abort_on_error ();
java_complete_class (); /* Parse unsatisfied class decl. */

File diff suppressed because it is too large Load Diff

View File

@ -3137,6 +3137,8 @@ register_fields (flags, type, variable_list)
TREE_CHAIN (init) = ctxp->static_initialized;
ctxp->static_initialized = init;
DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
if (TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
TREE_STATIC (TREE_OPERAND (TREE_OPERAND (init, 1), 0)) = 1;
}
/* A non-static field declared with an immediate initialization is
to be initialized in <init>, if any. This field is remembered
@ -4077,6 +4079,7 @@ do_resolve_class (class_type, decl, cl)
tree cl;
{
tree new_class_decl;
tree new_name;
tree original_name = NULL_TREE;
/* Do not try to replace TYPE_NAME (class_type) by a variable, since
@ -4100,6 +4103,7 @@ do_resolve_class (class_type, decl, cl)
if (!QUALIFIED_P (TYPE_NAME (class_type)) && ctxp->package)
TYPE_NAME (class_type) = merge_qualified_name (ctxp->package,
TYPE_NAME (class_type));
#if 1
if (!(new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
load_class (TYPE_NAME (class_type), 0);
if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
@ -4109,6 +4113,27 @@ do_resolve_class (class_type, decl, cl)
load_class (TYPE_NAME (class_type), 0);
return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
}
#else
new_name = TYPE_NAME (class_type);
if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_name)) != NULL_TREE)
{
if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
!CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
load_class (new_name, 0);
return IDENTIFIER_CLASS_VALUE (new_name);
}
else
{
tree class = read_class (new_name);
if (class != NULL_TREE)
{
tree decl = IDENTIFIER_CLASS_VALUE (new_name);
if (decl == NULL_TREE)
decl = push_class (class, new_name);
return decl;
}
}
#endif
TYPE_NAME (class_type) = original_name;
/* 3- Check an other compilation unit that bears the name of type */
@ -5486,6 +5511,7 @@ void
java_layout_classes ()
{
tree current;
int save_error_count = java_error_count;
/* Layout the methods of all classes seen so far */
java_layout_seen_class_methods ();
@ -5647,7 +5673,10 @@ java_complete_expand_method (mdecl)
PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
if (block_body != NULL_TREE)
block_body = java_complete_tree (block_body);
{
block_body = java_complete_tree (block_body);
check_for_initialization (block_body);
}
BLOCK_EXPR_BODY (fbody) = block_body;
if ((block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
@ -5786,6 +5815,7 @@ java_expand_finals ()
void
java_expand_classes ()
{
int save_error_count = java_error_count;
java_parse_abort_on_error ();
if (!(ctxp = ctxp_for_generation))
return;
@ -5876,6 +5906,11 @@ make_qualified_name (left, right, location)
tree left, right;
int location;
{
#ifdef USE_COMPONENT_REF
tree node = build (COMPONENT_REF, NULL_TREE, left, right);
EXPR_WFL_LINECOL (node) = location;
return node;
#else
tree left_id = EXPR_WFL_NODE (left);
tree right_id = EXPR_WFL_NODE (right);
tree wfl, merge;
@ -5896,6 +5931,7 @@ make_qualified_name (left, right, location)
EXPR_WFL_NODE (left) = merge;
return left;
#endif
}
/* Extract the last identifier component of the qualified in WFL. The
@ -9864,6 +9900,7 @@ patch_new_array_init (type, node)
TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
TREE_TYPE (node) = promote_type (type);
TREE_CONSTANT (init) = all_constant;
TREE_CONSTANT (node) = all_constant;
return node;
}
@ -11084,17 +11121,17 @@ fold_constant_for_init (node, context)
switch (code)
{
case MULT_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
case TRUNC_MOD_EXPR:
case RDIV_EXPR:
case LSHIFT_EXPR:
case RSHIFT_EXPR:
case URSHIFT_EXPR:
case BIT_AND_EXPR:
case BIT_XOR_EXPR:
case BIT_IOR_EXPR:
case TRUNC_MOD_EXPR:
case RDIV_EXPR:
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
case EQ_EXPR:
@ -11193,7 +11230,32 @@ fold_constant_for_init (node, context)
return val;
}
#ifdef USE_COMPONENT_REF
case IDENTIFIER:
case COMPONENT_REF:
?;
#endif
default:
return NULL_TREE;
}
}
#ifdef USE_COMPONENT_REF
/* Context is 'T' for TypeName, 'P' for PackageName,
'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
tree
resolve_simple_name (name, context)
tree name;
int context;
{
}
tree
resolve_qualified_name (name, context)
tree name;
int context;
{
}
#endif