This is the mail archive of the java@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]

Re: Strange, elusive bug in boolean return values with latest fetch from cvs


Okay, so I can duplicate your test case!

Here's a partial patch.  Its result is:


.globl BugJune3.seeIfItsTrue()                          .globl BugJune3.seeIfItsTrue()
        .type   BugJune3.seeIfItsTrue(), @function                      .type   BugJune3.seeIfItsTrue(), @function
BugJune3.seeIfItsTrue():                                        BugJune3.seeIfItsTrue():
.LFB3:                                                          .LFB3:
        pushq   %rbp                                                    pushq   %rbp
.LCFI5:                                                         .LCFI5:
        movq    8(%rdi), %rdi                                           movq    8(%rdi), %rdi
                                                              >         xorl    %eax, %eax
        movq    %rsp, %rbp                                              movq    %rsp, %rbp
.LCFI6:                                                         .LCFI6:
        testq   %rdi, %rdi                                              testq   %rdi, %rdi
        je      .L3                                           |         je      .L5
.L4:                                                          | .L3:
        movq    (%rdi), %rax                                            movq    (%rdi), %rax
        call    *56(%rax)                                               call    *56(%rax)
.L3:                                                          |         movzbl  %al, %eax
                                                              > .L5:
        leave                                                           leave
        xorl    %eax, %eax                                    <
        ret                                                             ret
.LFE3:                                                          .LFE3:
        .size   BugJune3.seeIfItsTrue(), .-_ZN8BugJune31                .size   BugJune3.seeIfItsTrue(), .-_ZN8BugJune31


The problem seems to be due to the fact that the type system of the
Java Virtual Machine is subtly different from the type system of the
Java Programming Language.  In particular, booleans and ints are
incompatible in the source language but are both treated as integer
types in the VM.  So, treating these as distinct types when compiling
bytecode is incorrect.

What we do at the moment is basically wrong, in that if we have two
sources and one destination, and one source is int and the other
boolean, then they are treated as distinct variables.

Look at this fragment:

  7: iconst_0
  8: goto 18
 11: aload_0
 12: getfield #4=<Field BugJune3.littleThing BugJune3$LittleThing>
 15: invokevirtual #5=<Method BugJune3$LittleThing.isTrue ()boolean>
 18: ireturn

insn 7 pushes an int, and insn 15 pushes a boolean.  insn 18 returns
something, and the compiler doesn't believe that these types are
compatible.  So, when the compiler wants a temporary to hold the
result of insn 15, it generates a new one instead of using the same
one that was generated for insn 7.  And, of course, that value is
lost.

So, when we create a temporary for an item on the evaluation stack, we
need to create an int, even if the insn that created it returned a
boolean.

This patch forces all pushes of booleans onto the operand stack to be
converted to ints.  I don't think it is totally correct, but it's
better.

I have't tested it at all: see how you get on.

Andrew.

2004-06-09  Andrew Haley  <aph@redhat.com>

	* expr.c (flush_quick_stack): Perform type conversion when
	building our MODIFY_EXPR.
	(push_type_0): Treat booleans pushed onto the stack as ints.
	(push_value): Likewise.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.192
diff -p -2 -c -w -r1.192 expr.c
*** expr.c	8 Jun 2004 13:27:38 -0000	1.192
--- expr.c	9 Jun 2004 19:04:32 -0000
*************** flush_quick_stack (void)
*** 240,244 ****
--- 240,248 ----
        decl = find_stack_slot (stack_index, type);
        if (decl != node)
+ 	{
+ 	  if (TREE_TYPE (node) != TREE_TYPE (decl))
+ 	    decl = convert (TREE_TYPE (node), decl);
  	  java_add_stmt (build (MODIFY_EXPR, TREE_TYPE (node), decl, node));
+ 	}
        stack_index += 1 + TYPE_IS_WIDE (type);
      }
*************** push_type_0 (tree type)
*** 253,256 ****
--- 257,264 ----
    int n_words;
    type = promote_type (type);
+   /* Although Java local variables may be of boolean type, the Java VM
+      treats them as though they're integers.  */
+   if (type == promoted_boolean_type_node)
+     type = int_type_node;
    n_words = 1 + TYPE_IS_WIDE (type);
    if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
*************** push_value (tree value)
*** 277,280 ****
--- 285,292 ----
      {
        type = promote_type (type);
+       /* Although Java local variables may be of boolean type, the Java VM
+ 	 treats them as though they're integers.  */
+       if (type == promoted_boolean_type_node)
+ 	type = int_type_node;
        value = convert (type, value);
      }


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