aboutsummaryrefslogtreecommitdiff
path: root/gcc/java
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2006-03-31 11:43:43 +0000
committerAndrew Haley <aph@gcc.gnu.org>2006-03-31 11:43:43 +0000
commite6b7893e348494a1fe572cc149d5044998d55a19 (patch)
tree8bf22cfbf415d9728bf595db481e2380c8f33e95 /gcc/java
parent9ef47dec918a7b32927f240581d9418981050170 (diff)
downloadgcc-e6b7893e348494a1fe572cc149d5044998d55a19.zip
gcc-e6b7893e348494a1fe572cc149d5044998d55a19.tar.gz
gcc-e6b7893e348494a1fe572cc149d5044998d55a19.tar.bz2
re PR libgcj/26858 (NullPointerException not generated for large classes...)
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. From-SVN: r112574
Diffstat (limited to 'gcc/java')
-rw-r--r--gcc/java/ChangeLog11
-rw-r--r--gcc/java/class.c12
-rw-r--r--gcc/java/expr.c30
-rw-r--r--gcc/java/lang.c11
4 files changed, 59 insertions, 5 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 6d705fb..e40d443 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,14 @@
+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.
+
2006-03-30 Carlos O'Donell <carlos@codesourcery.com>
* Make-lang.in: Rename docdir to gcc_docdir.
diff --git a/gcc/java/class.c b/gcc/java/class.c
index bce1677..a607451 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -681,7 +681,17 @@ build_java_method_type (tree fntype, tree this_class, int access_flags)
{
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
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 785ccc4..c178552 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -130,6 +130,10 @@ static GTY(()) tree quick_stack;
/* A free-list of unused permanent TREE_LIST nodes. */
static GTY((deletable)) tree tree_list_free_list;
+/* The physical memory page size used in this computer. See
+ build_field_ref(). */
+static GTY(()) tree page_size;
+
/* The stack pointer of the Java virtual machine.
This does include the size of the quick_stack. */
@@ -1678,11 +1682,28 @@ build_field_ref (tree self_value, tree self_class, tree name)
}
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
+ Page 0: this is necessary on those GNU/Linux/BSD systems that
+ trap SEGV to generate NullPointerExceptions.
+
+ We assume that Page 0 will be mapped with NOPERM, and that
+ memory may be allocated from any other page, so only field
+ offsets < pagesize are guaratneed to trap. We also assume
+ the smallest page size we'll encounter is 4k bytes. */
+ if (check && ! flag_check_references && ! flag_indirect_dispatch)
+ {
+ tree field_offset = byte_position (field_decl);
+ if (! page_size)
+ page_size = size_int (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 @@ build_field_ref (tree self_value, tree self_class, tree name)
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)),
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index e1f822e..58f23e9 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -108,6 +108,14 @@ const char *const tree_code_name[] = {
};
#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 @@ struct language_function GTY(())
#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;