Unspecified behaviour in java/gjavah.c

Diego Novillo dnovillo@redhat.com
Mon Nov 25 03:19:00 GMT 2002


After the latest merge from basic-improvements to tree-ssa, I
started getting failures building libjava:
-----------------------------------------------------------------------------
+ ../../gcc/gcjh -classpath '' -bootclasspath . java/lang/ThreadLocal
Premature end of .class file ./java/lang/ThreadLocal.class.
-----------------------------------------------------------------------------
I tracked down the problem to java/jcf-reader.c:skip_attribute. The
.i file contains this:
-----------------------------------------------------------------------------
 1	static void
 2	skip_attribute (jcf, number_of_attribute)
 3	 JCF *jcf;
 4	 int number_of_attribute;
 5	{
 6	 while (number_of_attribute--)
 7	 {
 8	 ((jcf)->read_end-(jcf)->read_ptr >= (6) ? 0 : (*(jcf)->filbuf)(jcf, 6));
 9	 (void) ((jcf)->read_ptr += 2, ((((jcf)->read_ptr-2)[0] << 8) | (((jcf)->read_ptr-2)[1])));
 10	 ((jcf)->read_ptr += (((jcf)->read_ptr += 4, (((unsigned long)((jcf)->read_ptr-4)[0] << 24) | ((unsigned long)((jcf)->read_ptr-4)[1] << 16) | ((unsigned long)((jcf)->read_ptr-4)[2] << 8) | ((unsigned long)((jcf)->read_ptr-4)[3])))));
 11	 }
 12	}
-----------------------------------------------------------------------------
The problematic line is 10. When we convert it to GIMPLE form,
the pre-merge version works fine, but the post-merge version
causes gjh to mess up the file pointer. After discussing it with
a few folks, the consensus is that the code is invoking
unspecified behaviour.
Below is a minimal test case that exhibits the same problem:
-----------------------------------------------------------------------------
struct JCF {
 char *read_ptr;
} *jcf;
foo()
{
 jcf->read_ptr += (jcf->read_ptr += 4, 5);
}
-----------------------------------------------------------------------------
This is how the gimplified version looks like with the pre-merged
(good, on the left) and post-merged (bad, on the right) branch:
-----------------------------------------------------------------------------
$ diff -y -W80 good.c.t04.simple bad.c.t04.simple 
foo() foo()
{ {
 char * T.1; char * T.1;
 char * T.2; char * T.2;
 T.1 = jcf->read_ptr; T.1 = jcf->read_ptr;
 jcf->read_ptr = T.1 + 4B; <
 T.2 = jcf->read_ptr; T.2 = jcf->read_ptr;
 jcf->read_ptr = T.2 + 5B | jcf->read_ptr = T.2 + 4B;
 > jcf->read_ptr = T.1 + 5B
} }
-----------------------------------------------------------------------------
The reason why the two versions get gimplified differently is
because the front end is actually emitting different trees. This
is the tree that the pre-merge gimplifier receives:
--- Pre-merge ---------------------------------------------------------------
Breakpoint 1, simplify_function_tree (fndecl=0x40079740)
 at /home/dnovillo/tree-ssa/src/gcc/gimplify.c:122
[ ... ]
(gdb) call print_c_tree(stdout,fnbody)
{ 
 jcf->read_ptr = jcf->read_ptr = jcf->read_ptr + 4B, jcf->read_ptr + 5B;
}
-----------------------------------------------------------------------------
And this is the tree that the post-merge gimplifier receives:
--- Post-merge --------------------------------------------------------------
Breakpoint 1, simplify_function_tree (fndecl=0x4007c4fc)
 at /home/dnovillo/merge-tree-ssa/src/gcc/gimplify.c:122
[ ... ]
(gdb) call print_c_tree (stdout,fnbody)
{
 jcf->read_ptr = jcf->read_ptr + (jcf->read_ptr = jcf->read_ptr + 4B, 5B);
}
-----------------------------------------------------------------------------
I have modified jcf-reader.c to avoid this, but I don't know the
code very well. Is the patch below appropriate?
Thanks. Diego.
	* java/jcf-reader.c: Don't expand JCF_readu4 inside the
	expansion of JCF_SKIP.
Index: jcf-reader.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-reader.c,v
retrieving revision 1.15
diff -d -u -p -r1.15 jcf-reader.c
--- jcf-reader.c	23 Mar 2001 19:42:25 -0000	1.15
+++ jcf-reader.c	25 Nov 2002 00:27:23 -0000
@@ -96,9 +96,11 @@ skip_attribute (jcf, number_of_attribute
 {
 while (number_of_attribute--)
 {
+ JCF_u4 N;
 JCF_FILL (jcf, 6);
 (void) JCF_readu2 (jcf);
- JCF_SKIP (jcf, JCF_readu4 (jcf));
+ N = JCF_readu4 (jcf);
+ JCF_SKIP (jcf, N);
 }
 }
 #endif


More information about the Java mailing list

AltStyle によって変換されたページ (->オリジナル) /