diff options
-rw-r--r-- | gcc/java/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/java/decl.c | 26 | ||||
-rw-r--r-- | gcc/java/expr.c | 27 |
3 files changed, 50 insertions, 13 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index e4cc2ff..22f9176 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,13 @@ +2005-02-14 Andrew Haley <aph@redhat.com> + + PR java/19907 + * expr.c (expand_byte_code): Call promote_arguments(). + (promote_arguments): New function. + * decl.c (check_local_unnamed_variable): Remve special case for + new verifier. + (find_local_variable): Promote all boolean types to int + when searching for local variable decls. + 2005-02-12 Kazu Hirata <kazu@cs.umass.edu> * builtins.c, java-except.h, jcf-parse.c, jv-scan.c, lex.c, diff --git a/gcc/java/decl.c b/gcc/java/decl.c index ad1b55e..b7aa616 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -263,24 +263,14 @@ check_local_unnamed_variable (tree best, tree decl, tree type) initially held a pointer arg -- or vice versa -- we create a new VAR_DECL. - ???: As long as verification is correct, this will be a + ???: As long as verification is correct, this will be a compatible type. But maybe we should create a dummy variable and replace all references to it with the DECL and a - NOP_EXPR. + NOP_EXPR. */ || (TREE_CODE (decl_type) == POINTER_TYPE && TREE_CODE (decl) == PARM_DECL - && TREE_CODE (type) == POINTER_TYPE) - - /* The new verifier requires a similar treatment in the - situation where the parameter has an integral type which - promotes to `int'. */ - || (flag_new_verifier - && TREE_CODE (decl) == PARM_DECL - && INTEGRAL_TYPE_P (decl_type) - && TYPE_PRECISION (decl_type) <= 32 - && INTEGRAL_TYPE_P (type) - && TYPE_PRECISION (type) <= 32)) + && TREE_CODE (type) == POINTER_TYPE)) { if (best == NULL_TREE || (decl_type == type && TREE_TYPE (best) != type)) @@ -312,6 +302,16 @@ find_local_variable (int index, tree type, int pc ATTRIBUTE_UNUSED) tmp = DECL_LOCAL_SLOT_CHAIN (tmp); } + /* gcj has a function called promote_type(), which is used by both + the bytecode compiler and the source compiler. Unfortunately, + the type systems for the Java VM and the Java language are not + the same: a boolean in the VM promotes to an int, not to a wide + boolean. If our caller wants something to hold a boolean, that + had better be an int, because that slot might be re-used + later in integer context. */ + if (TREE_CODE (type) == BOOLEAN_TYPE) + type = integer_type_node; + /* If we don't find a match, create one with the type passed in. The name of the variable is #n#m, which n is the variable index in the local variable area and m is a dummy identifier for diff --git a/gcc/java/expr.c b/gcc/java/expr.c index a8ae7c6..7d51505 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -86,6 +86,7 @@ static void java_stack_pop (int); static tree build_java_throw_out_of_bounds_exception (tree); static tree build_java_check_indexed_type (tree, tree); static unsigned char peek_opcode_at_pc (struct JCF *, int, int); +static void promote_arguments (void); static GTY(()) tree operand_type[59]; @@ -2961,6 +2962,8 @@ expand_byte_code (JCF *jcf, tree method) return; } + promote_arguments (); + /* Translate bytecodes. */ linenumber_pointer = linenumber_table; for (PC = 0; PC < length;) @@ -3643,4 +3646,28 @@ build_java_empty_stmt (void) return t; } +/* Promote all args of integral type before generating any code. */ + +static void +promote_arguments (void) +{ + int i; + tree arg; + for (arg = DECL_ARGUMENTS (current_function_decl), i = 0; + arg != NULL_TREE; arg = TREE_CHAIN (arg), i++) + { + tree arg_type = TREE_TYPE (arg); + if (INTEGRAL_TYPE_P (arg_type) + && TYPE_PRECISION (arg_type) < 32) + { + tree copy = find_local_variable (i, integer_type_node, -1); + java_add_stmt (build2 (MODIFY_EXPR, integer_type_node, + copy, + fold_convert (integer_type_node, arg))); + } + if (TYPE_IS_WIDE (arg_type)) + i++; + } +} + #include "gt-java-expr.h" |