gcj.texi (Configure-time Options): Add -fcheck-references.
authorAndrew Haley <aph@redhat.com>
Fri, 23 Mar 2001 14:16:33 +0000 (14:16 +0000)
committerAndrew Haley <aph@gcc.gnu.org>
Fri, 23 Mar 2001 14:16:33 +0000 (14:16 +0000)
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

gcc/java/ChangeLog
gcc/java/expr.c
gcc/java/gcj.texi
gcc/java/java-tree.h
gcc/java/jvspec.c
gcc/java/lang.c

index 387b415..5ad64ee 100644 (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.
index 4f7c0dc..8be7f7d 100644 (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)
-    {
-      /* 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:
index af2eded..c31a923 100644 (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
 
 
index 8dd98ba..6e3c979 100644 (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));
index 9a3efea..105f813 100644 (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}}\
index 1680d99..38aedc7 100644 (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