# HG changeset patch # User acorn # Date 1377692101 14400 # Node ID 915cc4f3fb151da1ba862f273b714348e1b0bff1 # Parent c26d57fa08aa4bc5df01a37963e659cb3b867cfc 8020489: VM crash when non-existent interface called by invokespecial Reviewed-by: kamg, coleenp diff -r c26d57fa08aa -r 915cc4f3fb15 src/share/vm/classfile/defaultMethods.cpp --- a/src/share/vm/classfile/defaultMethods.cpp Tue Aug 27 16:02:59 2013 -0400 +++ b/src/share/vm/classfile/defaultMethods.cpp Wed Aug 28 08:15:01 2013 -0400 @@ -870,7 +870,6 @@ : ShadowChecker(thread, name, holder, target) {} }; - // Find the unique qualified candidate from the perspective of the super_class // which is the resolved_klass, which must be an immediate superinterface // of klass @@ -884,43 +883,48 @@ if (family != NULL) { family->determine_target(current_class, CHECK_NULL); // get target from current_class - } - if (family->has_target()) { - Method* target = family->get_selected_target(); - InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); + if (family->has_target()) { + Method* target = family->get_selected_target(); + InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); - // Verify that the identified method is valid from the context of - // the current class, which is the caller class for invokespecial - // link resolution, i.e. ensure there it is not shadowed. - // You can use invokespecial to disambiguate interface methods, but - // you can not use it to skip over an interface method that would shadow it. - ErasedShadowChecker checker(THREAD, target->name(), holder, super_class); - checker.run(current_class); + // Verify that the identified method is valid from the context of + // the current class, which is the caller class for invokespecial + // link resolution, i.e. ensure there it is not shadowed. + // You can use invokespecial to disambiguate interface methods, but + // you can not use it to skip over an interface method that would shadow it. + ErasedShadowChecker checker(THREAD, target->name(), holder, super_class); + checker.run(current_class); - if (checker.found_shadow()) { + if (checker.found_shadow()) { #ifndef PRODUCT - if (TraceDefaultMethods) { - tty->print_cr(" Only candidate found was shadowed."); - } + if (TraceDefaultMethods) { + tty->print_cr(" Only candidate found was shadowed."); + } #endif // ndef PRODUCT - THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), - "Accessible default method not found", NULL); - } else { + THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), + "Accessible default method not found", NULL); + } else { #ifndef PRODUCT - if (TraceDefaultMethods) { - family->print_sig_on(tty, target->signature(), 1); - } + if (TraceDefaultMethods) { + family->print_sig_on(tty, target->signature(), 1); + } #endif // ndef PRODUCT - return target; - } + return target; + } + } else { + assert(family->throws_exception(), "must have target or throw"); + THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), + family->get_exception_message()->as_C_string(), NULL); + } } else { - assert(family->throws_exception(), "must have target or throw"); - THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), - family->get_exception_message()->as_C_string(), NULL); + // no method found + ResourceMark rm(THREAD); + THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), + Method::name_and_sig_as_C_string(current_class, + method_name, sig), NULL); } } - // This is called during linktime when we find an invokespecial call that // refers to a direct superinterface. It indicates that we should find the // default method in the hierarchy of that superinterface, and if that method