aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2001-03-23 14:16:33 +0000
committerAndrew Haley <aph@gcc.gnu.org>2001-03-23 14:16:33 +0000
commit4ff17c6a1a1a22ba947b50e04d83110821170d13 (patch)
tree08a50666c0e7391b2df66372456f9a01f3b4e195 /gcc
parent8e4ce833ab3f109b5d344a84d0659a895aa8c603 (diff)
downloadgcc-4ff17c6a1a1a22ba947b50e04d83110821170d13.zip
gcc-4ff17c6a1a1a22ba947b50e04d83110821170d13.tar.gz
gcc-4ff17c6a1a1a22ba947b50e04d83110821170d13.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/java/ChangeLog16
-rw-r--r--gcc/java/expr.c104
-rw-r--r--gcc/java/gcj.texi6
-rw-r--r--gcc/java/java-tree.h5
-rw-r--r--gcc/java/jvspec.c1
-rw-r--r--gcc/java/lang.c6
6 files changed, 86 insertions, 52 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 387b415..5ad64ee 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -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.
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 4f7c0dc..8be7f7d 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -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)
- {
- /* 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);
+ if (check != NULL_TREE)
+ {
+ 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:
diff --git a/gcc/java/gcj.texi b/gcc/java/gcj.texi
index af2eded..c31a923 100644
--- a/gcc/java/gcj.texi
+++ b/gcc/java/gcj.texi
@@ -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
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 8dd98ba..6e3c979 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -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));
diff --git a/gcc/java/jvspec.c b/gcc/java/jvspec.c
index 9a3efea..105f813 100644
--- a/gcc/java/jvspec.c
+++ b/gcc/java/jvspec.c
@@ -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}}\
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index 1680d99..38aedc7 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -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