diff options
author | Andrew Haley <aph@redhat.com> | 2006-03-31 11:43:43 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2006-03-31 11:43:43 +0000 |
commit | e6b7893e348494a1fe572cc149d5044998d55a19 (patch) | |
tree | 8bf22cfbf415d9728bf595db481e2380c8f33e95 /gcc/java | |
parent | 9ef47dec918a7b32927f240581d9418981050170 (diff) | |
download | gcc-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/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/java/class.c | 12 | ||||
-rw-r--r-- | gcc/java/expr.c | 30 | ||||
-rw-r--r-- | gcc/java/lang.c | 11 |
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; |