-
Bug
-
Resolution: Fixed
-
P3
-
repo-valhalla
As a leftover from the initial proposal to modify invokespecial for use with private nestmate method invocation we have this code in LinkResolver::linktime_resolve_special_method:
! // check if invokespecial's interface method reference is in an indirect superinterface
Klass* current_klass = link_info.current_klass();
if (current_klass != NULL && resolved_klass->is_interface()) {
InstanceKlass* ck = InstanceKlass::cast(current_klass);
InstanceKlass *klass_to_check = !ck->is_anonymous() ?
ck :
--- 1144,1155 ----
resolved_method->signature()->as_C_string()
);
return NULL;
}
! // check that invokespecial's interface method reference is in a direct superinterface,
! // unless we are dealing with nestmates.
Klass* current_klass = link_info.current_klass();
if (current_klass != NULL && resolved_klass->is_interface()) {
InstanceKlass* ck = InstanceKlass::cast(current_klass);
InstanceKlass *klass_to_check = !ck->is_anonymous() ?
ck :
*** 1122,1136 ****
// Disable verification for the dynamically-generated reflection bytecodes.
bool is_reflect = klass_to_check->is_subclass_of(
SystemDictionary::reflect_MagicAccessorImpl_klass());
if (!is_reflect &&
! !klass_to_check->is_same_or_direct_interface(resolved_klass)) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf),
! "Interface method reference: %s, is in an indirect superinterface of %s",
Method::name_and_sig_as_C_string(resolved_klass,
resolved_method->name(),
resolved_method->signature()),
current_klass->external_name());
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
--- 1157,1173 ----
// Disable verification for the dynamically-generated reflection bytecodes.
bool is_reflect = klass_to_check->is_subclass_of(
SystemDictionary::reflect_MagicAccessorImpl_klass());
if (!is_reflect &&
! !klass_to_check->is_same_or_direct_interface(resolved_klass) &&
! (ck == klass_to_check && // don't check nestmate access for anonymous classes
! !klass_to_check->has_nestmate_access_to(InstanceKlass::cast(resolved_klass), THREAD))) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf),
! "Interface method reference: %s, is not in a direct superinterface of %s",
Method::name_and_sig_as_C_string(resolved_klass,
resolved_method->name(),
resolved_method->signature()),
current_klass->external_name());
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
This code can be removed now that we use invokeinterface for private interface method invocations. No verifiable use of invokespecial would reach the nestmate access check.
! // check if invokespecial's interface method reference is in an indirect superinterface
Klass* current_klass = link_info.current_klass();
if (current_klass != NULL && resolved_klass->is_interface()) {
InstanceKlass* ck = InstanceKlass::cast(current_klass);
InstanceKlass *klass_to_check = !ck->is_anonymous() ?
ck :
--- 1144,1155 ----
resolved_method->signature()->as_C_string()
);
return NULL;
}
! // check that invokespecial's interface method reference is in a direct superinterface,
! // unless we are dealing with nestmates.
Klass* current_klass = link_info.current_klass();
if (current_klass != NULL && resolved_klass->is_interface()) {
InstanceKlass* ck = InstanceKlass::cast(current_klass);
InstanceKlass *klass_to_check = !ck->is_anonymous() ?
ck :
*** 1122,1136 ****
// Disable verification for the dynamically-generated reflection bytecodes.
bool is_reflect = klass_to_check->is_subclass_of(
SystemDictionary::reflect_MagicAccessorImpl_klass());
if (!is_reflect &&
! !klass_to_check->is_same_or_direct_interface(resolved_klass)) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf),
! "Interface method reference: %s, is in an indirect superinterface of %s",
Method::name_and_sig_as_C_string(resolved_klass,
resolved_method->name(),
resolved_method->signature()),
current_klass->external_name());
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
--- 1157,1173 ----
// Disable verification for the dynamically-generated reflection bytecodes.
bool is_reflect = klass_to_check->is_subclass_of(
SystemDictionary::reflect_MagicAccessorImpl_klass());
if (!is_reflect &&
! !klass_to_check->is_same_or_direct_interface(resolved_klass) &&
! (ck == klass_to_check && // don't check nestmate access for anonymous classes
! !klass_to_check->has_nestmate_access_to(InstanceKlass::cast(resolved_klass), THREAD))) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf),
! "Interface method reference: %s, is not in a direct superinterface of %s",
Method::name_and_sig_as_C_string(resolved_klass,
resolved_method->name(),
resolved_method->signature()),
current_klass->external_name());
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
This code can be removed now that we use invokeinterface for private interface method invocations. No verifiable use of invokespecial would reach the nestmate access check.