gcj.texi (Configure-time Options): Add -fcheck-references.

2001-02-07  Andrew Haley  <aph@redhat.com>

        * gcj.texi (Configure-time Options): Add -fcheck-references.
        * expr.c (build_java_indirect_ref): New function.
        (build_java_array_length_access): Use build_java_indirect_ref to
        check for null references.
        (build_java_arrayaccess): Likewise.
        (build_get_class): Likewise.
        (build_field_ref): Likewise.
        (invoke_build_dtable): Likewise.
        (build_invokeinterface): Likewise.
        * lang.c (lang_f_options): Add flag_check_references.
        * jvspec.c (jvgenmain_spec): Add flag_check_references.
        * java-tree.h (flag_check_references): New variable.
        * lang.c (flag_check_references): Likewise.

From-SVN: r40780
This commit is contained in:
Andrew Haley 2001-03-23 14:16:33 +00:00 committed by Andrew Haley
parent 8e4ce833ab
commit 4ff17c6a1a
6 changed files with 85 additions and 51 deletions

View File

@ -1,3 +1,19 @@
2001-02-07 Andrew Haley <aph@redhat.com>
* gcj.texi (Configure-time Options): Add -fcheck-references.
* expr.c (build_java_indirect_ref): New function.
(build_java_array_length_access): Use build_java_indirect_ref to
check for null references.
(build_java_arrayaccess): Likewise.
(build_get_class): Likewise.
(build_field_ref): Likewise.
(invoke_build_dtable): Likewise.
(build_invokeinterface): Likewise.
* lang.c (lang_f_options): Add flag_check_references.
* jvspec.c (jvgenmain_spec): Add flag_check_references.
* java-tree.h (flag_check_references): New variable.
* lang.c (flag_check_references): Likewise.
2001-03-23 Bryce McKinlay <bryce@albatross.co.nz>
* gjavah.c (cxx_keywords): Update from the definitive list in cp/lex.c.

View File

@ -710,36 +710,46 @@ build_java_array_length_access (node)
length = java_array_type_length (type);
if (length >= 0)
return build_int_2 (length, 0);
return fold (build1 (INDIRECT_REF,
int_type_node,
return fold (build1 (INDIRECT_REF, int_type_node,
fold (build (PLUS_EXPR, ptr_type_node,
node,
java_check_reference (node, 1),
JAVA_ARRAY_LENGTH_OFFSET(node)))));
}
/* Optionally checks an array against the NULL pointer, eventually throwing a
NullPointerException. It could replace signal handling, but tied to NULL.
ARG1: the pointer to check, ARG2: the expression to use if
the pointer is non-null and ARG3 the type that should be returned. */
/* Optionally checks a reference against the NULL pointer. ARG1: the
expr, ARG2: we should check the reference. Don't generate extra
checks if we're not generating code. */
tree
java_check_reference (expr, check)
tree expr;
int check;
{
if (!flag_syntax_only && check)
{
tree cond;
expr = save_expr (expr);
cond = build (COND_EXPR, void_type_node,
build (EQ_EXPR, boolean_type_node, expr, null_pointer_node),
build (CALL_EXPR, void_type_node,
build_address_of (soft_nullpointer_node),
NULL_TREE, NULL_TREE),
empty_stmt_node);
expr = build (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
}
return expr;
}
/* Reference an object: just like an INDIRECT_REF, but with checking. */
tree
build_java_arraynull_check (node, expr, type)
tree node ATTRIBUTE_UNUSED;
tree expr;
tree type ATTRIBUTE_UNUSED;
build_java_indirect_ref (type, expr, check)
tree type;
tree expr;
int check;
{
#if 0
static int java_array_access_throws_null_exception = 0;
node = ???;
if (java_array_access_throws_null_exception)
return (build (COND_EXPR,
type,
build (EQ_EXPR, int_type_node, node, null_pointer_node),
build_java_athrow (node), expr ));
else
#endif
return (expr);
return build1 (INDIRECT_REF, type, java_check_reference (expr, check));
}
static tree
@ -792,15 +802,15 @@ build_java_arrayaccess (array, type, index)
TREE_SIDE_EFFECTS( throw ) = 1;
}
}
node = build1 (INDIRECT_REF, type,
fold (build (PLUS_EXPR, ptr_type_node,
array,
java_check_reference (array, flag_check_references),
(throw ? build (COMPOUND_EXPR, int_type_node,
throw, arith )
: arith))));
return (fold (build_java_arraynull_check (array, node, type)));
return node;
}
/* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
@ -1008,7 +1018,7 @@ expand_java_array_length ()
tree array = pop_value (ptr_type_node);
tree length = build_java_array_length_access (array);
push_value (build_java_arraynull_check (array, length, int_type_node));
push_value (length);
}
/* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
@ -1118,7 +1128,8 @@ build_get_class (value)
return build (COMPONENT_REF, class_ptr_type,
build1 (INDIRECT_REF, dtable_type,
build (COMPONENT_REF, dtable_ptr_type,
build1 (INDIRECT_REF, object_type_node, value),
build_java_indirect_ref (object_type_node, value,
flag_check_references),
vtable_field)),
class_field);
}
@ -1485,8 +1496,8 @@ build_field_ref (self_value, self_class, name)
#ifdef JAVA_USE_HANDLES
self_value = unhand_expr (self_value);
#endif
self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
self_value);
self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
self_value, flag_check_references);
return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
self_value, field_decl));
}
@ -1780,7 +1791,8 @@ invoke_build_dtable (is_invoke_interface, arg_list)
if (dtable_ident == NULL_TREE)
dtable_ident = get_identifier ("vtable");
dtable = build1 (INDIRECT_REF, object_type_node, objectref );
dtable = build_java_indirect_ref (object_type_node, objectref,
flag_check_references);
dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
lookup_field (&object_type_node, dtable_ident));
@ -1829,7 +1841,7 @@ build_invokeinterface (dtable, method)
ggc_add_tree_root (&class_ident, 1);
}
dtable = build1 (INDIRECT_REF, dtable_type, dtable);
dtable = build_java_indirect_ref (dtable_type, dtable, flag_check_references);
dtable = build (COMPONENT_REF, class_ptr_type, dtable,
lookup_field (&dtable_type, class_ident));
@ -1875,7 +1887,7 @@ expand_invoke (opcode, method_ref_index, nargs)
const char *self_name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
tree call, func, method, arg_list, method_type;
tree cond = NULL_TREE;
tree check = NULL_TREE;
if (! CLASS_LOADED_P (self_type))
{
@ -1957,7 +1969,7 @@ expand_invoke (opcode, method_ref_index, nargs)
the new `self' expression once. */
tree save_arg = save_expr (TREE_VALUE (arg_list));
TREE_VALUE (arg_list) = save_arg;
cond = build (EQ_EXPR, boolean_type_node, save_arg, null_pointer_node);
check = java_check_reference (save_arg, 1);
func = build_known_method_ref (method, method_type, self_type,
method_signature, arg_list);
}
@ -1974,20 +1986,9 @@ expand_invoke (opcode, method_ref_index, nargs)
call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1;
if (cond != NULL_TREE)
if (check != NULL_TREE)
{
/* We have to make the `then' branch a compound expression to
make the types turn out right. This seems bizarre. */
call = build (COND_EXPR, TREE_TYPE (call), cond,
build (COMPOUND_EXPR, TREE_TYPE (call),
build (CALL_EXPR, void_type_node,
build_address_of (soft_nullpointer_node),
NULL_TREE, NULL_TREE),
(FLOAT_TYPE_P (TREE_TYPE (call))
? build_real (TREE_TYPE (call), dconst0)
: build1 (CONVERT_EXPR, TREE_TYPE (call),
integer_zero_node))),
call);
call = build (COMPOUND_EXPR, TREE_TYPE (call), check, call);
TREE_SIDE_EFFECTS (call) = 1;
}
@ -2428,8 +2429,9 @@ java_lang_expand_expr (exp, target, tmode, modifier)
init = init_decl;
}
expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
build1 (INDIRECT_REF, array_type,
array_decl), data_fld), init, 0, 0);
build_java_indirect_ref (array_type,
array_decl, flag_check_references),
data_fld), init, 0, 0);
return tmp;
}
case BLOCK:

View File

@ -758,6 +758,12 @@ hash table and not in the object itself.
On some systems, a library routine is called to perform integer
division. This is required to get exception handling correct when
dividing by zero.
@item -fcheck-references
On some systems it's necessary to insert inline checks whenever
accessing an object via a reference. On other systems you won't need
this because null pointer accesses are caught automatically by the
processor.
@end table

View File

@ -181,6 +181,9 @@ extern int flag_use_boehm_gc;
object to its synchronization structure. */
extern int flag_hash_synchronization;
/* When non zero, generate checks for references to NULL. */
extern int flag_check_references;
/* Encoding used for source files. */
extern const char *current_encoding;
@ -1010,6 +1013,8 @@ extern tree build_anewarray PARAMS ((tree, tree));
extern tree build_new_array PARAMS ((tree, tree));
extern tree build_java_array_length_access PARAMS ((tree));
extern tree build_java_arraynull_check PARAMS ((tree, tree, tree));
extern tree build_java_indirect_ref PARAMS ((tree, tree, int));
extern tree java_check_reference PARAMS ((tree, int));
extern tree build_get_class PARAMS ((tree));
extern tree build_instanceof PARAMS ((tree, tree));
extern tree create_label_decl PARAMS ((tree));

View File

@ -63,6 +63,7 @@ const char jvgenmain_spec[] =
%{<fuse-boehm-gc} %{<fhash-synchronization} %{<fjni}\
%{<fclasspath*} %{<fCLASSPATH*} %{<foutput-class-dir}\
%{<fuse-divide-subroutine} %{<fno-use-divide-subroutine}\
%{<fcheck-references} %{<fno-check-references}\
%{f*} -fdollars-in-identifiers\
%{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\

View File

@ -138,6 +138,9 @@ int flag_jni = 0;
file. */
int flag_newer = 1;
/* When non zero, generate checks for references to NULL. */
int flag_check_references = 0;
/* The encoding of the source file. */
const char *current_encoding = NULL;
@ -164,7 +167,8 @@ lang_f_options[] =
{"use-divide-subroutine", &flag_use_divide_subroutine, 1},
{"use-boehm-gc", &flag_use_boehm_gc, 1},
{"hash-synchronization", &flag_hash_synchronization, 1},
{"jni", &flag_jni, 1}
{"jni", &flag_jni, 1},
{"check-references", &flag_check_references, 1},
};
static struct string_option