re PR java/26390 (Problem dispatching method call when method does not exist in superclass)

gcc/java
	PR java/26390:
	* class.c (get_interface_method_index): Don't put <clinit> into
	interface table.
libjava
	PR java/26390:
	* link.cc (get_interfaces): Skip <clinit>.
	(append_partial_itable): Likewise.

From-SVN: r112093
This commit is contained in:
Tom Tromey 2006-03-15 18:29:44 +00:00 committed by Tom Tromey
parent 2afd35b338
commit 88200a8dd1
4 changed files with 36 additions and 13 deletions

View File

@ -1,3 +1,9 @@
2006-03-15 Tom Tromey <tromey@redhat.com>
PR java/26390:
* class.c (get_interface_method_index): Don't put <clinit> into
interface table.
2006-03-15 Tom Tromey <tromey@redhat.com>
* parse.y (analyze_clinit_body): Ignore empty statements.

View File

@ -1,5 +1,5 @@
/* Functions related to building classes and their related objects.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of GCC.
@ -2303,18 +2303,21 @@ layout_class_methods (tree this_class)
TYPE_NVIRTUALS (this_class) = dtable_count;
}
/* Return the index of METHOD in INTERFACE. This index begins at 1 and is used as an
argument for _Jv_LookupInterfaceMethodIdx(). */
/* Return the index of METHOD in INTERFACE. This index begins at 1
and is used as an argument for _Jv_LookupInterfaceMethodIdx(). */
int
get_interface_method_index (tree method, tree interface)
{
tree meth;
int i = 1;
for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth))
{
if (meth == method)
return i;
/* We don't want to put <clinit> into the interface table. */
if (! ID_CLINIT_P (DECL_NAME (meth)))
++i;
gcc_assert (meth != NULL_TREE);
}
}

View File

@ -1,3 +1,9 @@
2006-03-15 Tom Tromey <tromey@redhat.com>
PR java/26390:
* link.cc (get_interfaces): Skip <clinit>.
(append_partial_itable): Likewise.
2006-03-10 Tom Tromey <tromey@redhat.com>
PR libgcj/25713:

View File

@ -699,9 +699,18 @@ _Jv_Linker::get_interfaces (jclass klass, _Jv_ifaces *ifaces)
result += get_interfaces (klass->interfaces[i], ifaces);
}
}
if (klass->isInterface())
result += klass->method_count + 1;
{
// We want to add 1 plus the number of interface methods here.
// But, we take special care to skip <clinit>.
++result;
for (int i = 0; i < klass->method_count; ++i)
{
if (klass->methods[i].name->first() != '<')
++result;
}
}
else if (klass->superclass)
result += get_interfaces (klass->superclass, ifaces);
return result;
@ -817,7 +826,7 @@ _Jv_ThrowAbstractMethodError ()
// Returns the offset at which the next partial ITable should be appended.
jshort
_Jv_Linker::append_partial_itable (jclass klass, jclass iface,
void **itable, jshort pos)
void **itable, jshort pos)
{
using namespace java::lang::reflect;
@ -826,6 +835,10 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
for (int j=0; j < iface->method_count; j++)
{
// Skip '<clinit>' here.
if (iface->methods[j].name->first() == '<')
continue;
meth = NULL;
for (jclass cl = klass; cl; cl = cl->getSuperclass())
{
@ -836,12 +849,7 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
break;
}
if (meth && (meth->name->first() == '<'))
{
// leave a placeholder in the itable for hidden init methods.
itable[pos] = NULL;
}
else if (meth)
if (meth)
{
if ((meth->accflags & Modifier::STATIC) != 0)
throw new java::lang::IncompatibleClassChangeError