Commit 88200a8d by Tom Tromey Committed by Tom Tromey

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
parent 2afd35b3
2006-03-15 Tom Tromey <tromey@redhat.com> 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. * parse.y (analyze_clinit_body): Ignore empty statements.
2006-03-08 David Daney <ddaney@avtrex.com> 2006-03-08 David Daney <ddaney@avtrex.com>
......
/* Functions related to building classes and their related objects. /* 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. Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -2303,18 +2303,21 @@ layout_class_methods (tree this_class) ...@@ -2303,18 +2303,21 @@ layout_class_methods (tree this_class)
TYPE_NVIRTUALS (this_class) = dtable_count; TYPE_NVIRTUALS (this_class) = dtable_count;
} }
/* Return the index of METHOD in INTERFACE. This index begins at 1 and is used as an /* Return the index of METHOD in INTERFACE. This index begins at 1
argument for _Jv_LookupInterfaceMethodIdx(). */ and is used as an argument for _Jv_LookupInterfaceMethodIdx(). */
int int
get_interface_method_index (tree method, tree interface) get_interface_method_index (tree method, tree interface)
{ {
tree meth; tree meth;
int i = 1; 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) if (meth == method)
return i; 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); gcc_assert (meth != NULL_TREE);
} }
} }
......
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> 2006-03-10 Tom Tromey <tromey@redhat.com>
PR libgcj/25713: PR libgcj/25713:
......
...@@ -699,9 +699,18 @@ _Jv_Linker::get_interfaces (jclass klass, _Jv_ifaces *ifaces) ...@@ -699,9 +699,18 @@ _Jv_Linker::get_interfaces (jclass klass, _Jv_ifaces *ifaces)
result += get_interfaces (klass->interfaces[i], ifaces); result += get_interfaces (klass->interfaces[i], ifaces);
} }
} }
if (klass->isInterface()) 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) else if (klass->superclass)
result += get_interfaces (klass->superclass, ifaces); result += get_interfaces (klass->superclass, ifaces);
return result; return result;
...@@ -817,7 +826,7 @@ _Jv_ThrowAbstractMethodError () ...@@ -817,7 +826,7 @@ _Jv_ThrowAbstractMethodError ()
// Returns the offset at which the next partial ITable should be appended. // Returns the offset at which the next partial ITable should be appended.
jshort jshort
_Jv_Linker::append_partial_itable (jclass klass, jclass iface, _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
void **itable, jshort pos) void **itable, jshort pos)
{ {
using namespace java::lang::reflect; using namespace java::lang::reflect;
...@@ -826,6 +835,10 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface, ...@@ -826,6 +835,10 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
for (int j=0; j < iface->method_count; j++) for (int j=0; j < iface->method_count; j++)
{ {
// Skip '<clinit>' here.
if (iface->methods[j].name->first() == '<')
continue;
meth = NULL; meth = NULL;
for (jclass cl = klass; cl; cl = cl->getSuperclass()) for (jclass cl = klass; cl; cl = cl->getSuperclass())
{ {
...@@ -836,12 +849,7 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface, ...@@ -836,12 +849,7 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
break; break;
} }
if (meth && (meth->name->first() == '<')) if (meth)
{
// leave a placeholder in the itable for hidden init methods.
itable[pos] = NULL;
}
else if (meth)
{ {
if ((meth->accflags & Modifier::STATIC) != 0) if ((meth->accflags & Modifier::STATIC) != 0)
throw new java::lang::IncompatibleClassChangeError throw new java::lang::IncompatibleClassChangeError
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment