C++ and Java CNI: Check Java references

Cedric Berger cedric@wireless-networks.com
Mon Apr 23 12:15:00 GMT 2001


Shoudn't that be a #pragma put on the top of the CNI file?
Cedric


Andrew Haley wrote:

> The semantics of Java require dereferencing a null pointer to an
> object to throw a NullPointerException.  We already generate code to
> do this in the Java compiler; this patch is for CNI code that is
> written in C++.
>
> An alternative way to do this is to trap SEGV and throw an exception
> from a signal handler but not every processor/OS combination allows
> this, and we haven't ported code to do this to many systems.
>
> This patch only throws a NullPointerException from references to Java
> objects, not for arbitrary pointer dereferencing.  People writing CNI
> code had better check non-Java pointers themselves.
>
> I'm not absolutely sure where this option should be documented.
> Should it be documented anywhere other than in the gcj docs?
>
> There is an associated patch for libgcj that is required in order to
> use this option.
>
> Andrew.
>
> 2001-04-23  Andrew Haley  <aph@cambridge.redhat.com>
>
>         * lang-options.h: Document "-fcheck-java-references".
>         * decl2.c (flag_check_java_references): New flag.
>         * cp-tree.h (flag_check_java_references): New flag.
>         (lang_f_options): Set lang_check_java_references.
>         (check_java_reference): New function.
>         * call.c (check_java_reference): New function.
>         * typeck.c (build_indirect_ref): Call check_java_reference on Java
>         objects.
>
> Index: call.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
> retrieving revision 1.265
> diff -p -2 -c -r1.265 call.c
> *** call.c      2001/03/23 01:49:10     1.265
> --- call.c      2001/04/23 17:18:18
> *************** initialize_reference (type, expr)
> *** 5534,5535 ****
> --- 5534,5591 ----
>     return convert_like (conv, expr);
>   }
> +
> + static tree java_nullpointer_exception;
> +
> + tree
> + check_java_reference (exp)
> +      tree exp;
> + {
> +   tree e = exp;
> +
> +   if (!flag_check_java_references)
> +     return exp;
> +
> +   /* Strip off all pointer conversions and if the thing at the root is
> +      an integer we won't bother to check it.  The main reason for this
> +      is that offsetof is often defined as
> +
> +      ((size_t)&((type *)0)->memb)
> +
> +      which implicitly dereferences a null pointer.  Let's not check that.  */
> +
> +   while (TREE_CODE (e) == NOP_EXPR
> +        && TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE)
> +     (e) = TREE_OPERAND (e, 0);
> +
> +   if (TREE_CODE (e) == INTEGER_CST)
> +     return exp;
> +
> +   if (java_nullpointer_exception == NULL_TREE)
> +     {
> +       tree endlink = build_void_list_node ();
> +       java_nullpointer_exception
> +       = builtin_function ("_Jv_ThrowNullPointerException",
> +                           build_function_type (void_type_node, endlink),
> +                           0, NOT_BUILT_IN, NULL_PTR);
> +       TREE_THIS_VOLATILE (java_nullpointer_exception) = 1;
> +       TREE_SIDE_EFFECTS (java_nullpointer_exception) = 1;
> +       java_nullpointer_exception
> +       = build1 (ADDR_EXPR,
> +                 build_pointer_type
> +                 (TREE_TYPE (java_nullpointer_exception)),
> +                 java_nullpointer_exception);
> +       ggc_add_tree_root (&java_nullpointer_exception, 1);
> +     }
> +
> +   exp = stabilize_reference (exp);
> +   {
> +     tree cond = build (NE_EXPR, boolean_type_node, exp, integer_zero_node);
> +     tree bad =
> +       build (CALL_EXPR, void_type_node,
> +            java_nullpointer_exception,
> +            NULL_TREE, NULL_TREE);
> +     exp = build (COND_EXPR, TREE_TYPE (exp), cond, exp, bad);
> +   }
> +
> +   return exp;
> + }
> Index: cp-tree.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
> retrieving revision 1.590
> diff -p -2 -c -r1.590 cp-tree.h
> *** cp-tree.h   2001/03/26 08:37:24     1.590
> --- cp-tree.h   2001/04/23 17:18:28
> *************** extern int flag_access_control;
> *** 1146,1149 ****
> --- 1146,1153 ----
>   extern int flag_check_new;
>
> + /* Java objects: when non zero, generate checks for references to
> +    NULL.  */
> + extern int flag_check_java_references;
> +
>   /* Nonnull if we want to dump class heirarchies. */
>
> *************** extern tree initialize_reference
> *** 3699,3702 ****
> --- 3703,3707 ----
>   extern tree strip_top_quals                     PARAMS ((tree));
>   extern tree perform_implicit_conversion         PARAMS ((tree, tree));
> + extern tree check_java_reference              PARAMS ((tree));
>
>   /* in class.c */
> Index: decl2.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
> retrieving revision 1.448
> diff -p -2 -c -r1.448 decl2.c
> *** decl2.c     2001/03/22 00:55:11     1.448
> --- decl2.c     2001/04/23 17:18:38
> *************** int flag_enforce_eh_specs = 1;
> *** 448,451 ****
> --- 448,455 ----
>   c_language_kind c_language = clk_cplusplus;
>
> + /* Java objects: when non zero, generate checks for references to
> +    NULL.  */
> + int flag_check_java_references = 0;
> +
>   /* Table of language-dependent -f options.
>      STRING is the option name.  VARIABLE is the address of the variable.
> *************** lang_f_options[] =
> *** 471,474 ****
> --- 475,479 ----
>     {"access-control", &flag_access_control, 1},
>     {"check-new", &flag_check_new, 1},
> +   {"check-java-references", &flag_check_java_references, 1},
>     {"conserve-space", &flag_conserve_space, 1},
>     {"const-strings", &flag_const_strings, 1},
> Index: lang-options.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/cp/lang-options.h,v
> retrieving revision 1.37
> diff -p -2 -c -r1.37 lang-options.h
> *** lang-options.h      2001/01/05 19:12:19     1.37
> --- lang-options.h      2001/04/23 17:18:40
> *************** DEFINE_LANG_NAME ("C++")
> *** 112,115 ****
> --- 112,116 ----
>     { "-fxref", "Emit cross referencing information" },
>     { "-fno-xref", "" },
> +   { "-fcheck-java-references", "Generate null pointer checks for Java objects" },
>
>     { "-Wreturn-type", "Warn about inconsistent return types" },
> Index: typeck.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
> retrieving revision 1.342
> diff -p -2 -c -r1.342 typeck.c
> *** typeck.c    2001/03/06 20:45:05     1.342
> --- typeck.c    2001/04/23 17:18:45
> *************** build_indirect_ref (ptr, errorstring)
> *** 2380,2384 ****
>         else
>         {
> !         tree ref = build1 (INDIRECT_REF, t, pointer);
>
>           /* We *must* set TREE_READONLY when dereferencing a pointer to const,
> --- 2380,2388 ----
>         else
>         {
> !         tree ref
> !           = build1 (INDIRECT_REF, t,
> !                     TYPE_FOR_JAVA (t) && AGGREGATE_TYPE_P (t)
> !                     ? check_java_reference (pointer)
> !                     : pointer);
>
>           /* We *must* set TREE_READONLY when dereferencing a pointer to const,



More information about the Java mailing list