This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR java/26858: NullPointerException not generated for large classes...


This adds null pointer checks to field accesses except those via
"this".  Such field accesses are in practice fairly rare.

I assume that no system on which we catch SEGV has memory that is
mapped below 4k bytes.  On systems that do map memory below 4kbytes,
we will not be able to catch SEGV and we'll have to generate inline
null pointer checks instead.

Andrew.


2006-03-30  Andrew Haley  <aph@redhat.com>

	PR java/26858
	* lang.c (java_attribute_table): New.
	(LANG_HOOKS_ATTRIBUTE_TABLE): Define.
	* expr.c (build_field_ref): Add a null pointer check for all
	fields of offset > 4k.  Don't do so for accesses via the this
	pointer, which we know can never be null.
	* class.c (build_java_method_type): Mark arg 1 of all nonstatic
	methods nonnull.

Index: class.c
===================================================================
--- class.c	(revision 112491)
+++ class.c	(working copy)
@@ -681,7 +681,17 @@
 {
   if (access_flags & ACC_STATIC)
     return fntype;
-  return build_method_type (this_class, fntype);
+  fntype = build_method_type (this_class, fntype);
+
+  /* We know that arg 1 of every nonstatic method is non-null; tell
+     the back-end so.  */
+  TYPE_ATTRIBUTES (fntype) = (tree_cons 
+			      (get_identifier ("nonnull"),
+			       tree_cons (NULL_TREE, 
+					  build_int_cst (NULL_TREE, 1),
+					  NULL_TREE),
+			       TYPE_ATTRIBUTES (fntype)));
+  return fntype;
 }
 
 tree
Index: expr.c
===================================================================
--- expr.c	(revision 112491)
+++ expr.c	(working copy)
@@ -1678,11 +1678,32 @@
     }
   else
     {
-      int check = (flag_check_references
-		   && ! (DECL_P (self_value)
-			 && DECL_NAME (self_value) == this_identifier_node));
-
       tree base_type = promote_type (base_class);
+
+      /* CHECK is true if self_value is not the this pointer.  */
+      int check = (! (DECL_P (self_value)
+		      && DECL_NAME (self_value) == this_identifier_node));
+
+      /* Determine whether a field offset from NULL will lie within
+	 the first page of memory; this is necessary on those
+	 GNU/Linux/BSD systems that trap SEGV to generate
+	 NullPointerExceptions.  We assume that memory is allocated
+	 from the first page upwards, and the smallest page size we'll
+	 usually encounter is 4k bytes.  We also assume that page zero
+	 will be mapped with NOPERM.  */
+      if (check && ! flag_check_references && ! flag_indirect_dispatch)
+	{
+	  tree field_offset = DECL_FIELD_OFFSET (field_decl);
+	  if (field_offset)
+	    {
+	      static tree PAGE_SIZE;
+	      if (! PAGE_SIZE)
+		PAGE_SIZE = build_int_cstu (sizetype, 4096); 
+	      
+	      check = ! INT_CST_LT_UNSIGNED (field_offset, PAGE_SIZE);
+	    }
+	}
+
       if (base_type != TREE_TYPE (self_value))
 	self_value = fold_build1 (NOP_EXPR, base_type, self_value);
       if (! flag_syntax_only && flag_indirect_dispatch)
@@ -1708,6 +1729,7 @@
 			field_offset);
 	  
 	  field_offset = fold (convert (sizetype, field_offset));
+	  self_value = java_check_reference (self_value, check);
 	  address 
 	    = fold_build2 (PLUS_EXPR, 
 			   build_pointer_type (TREE_TYPE (field_decl)),
Index: lang.c
===================================================================
--- lang.c	(revision 112491)
+++ lang.c	(working copy)
@@ -108,6 +108,14 @@
 };
 #undef DEFTREECODE
 
+/* Table of machine-independent attributes.  */
+const struct attribute_spec java_attribute_table[] =
+{
+ { "nonnull",                0, -1, false, true, true,
+			      NULL },
+  { NULL,                     0, 0, false, false, false, NULL }
+};
+
 /* Used to avoid printing error messages with bogus function
    prototypes.  Starts out false.  */
 static bool inhibit_error_function_printing;
@@ -213,6 +221,9 @@
 #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
 #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME java_mangle_decl
 
+#undef LANG_HOOKS_ATTRIBUTE_TABLE
+#define LANG_HOOKS_ATTRIBUTE_TABLE java_attribute_table
+
 /* Each front end provides its own.  */
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]