8286277: CDS VerifyError when calling clone() on object array
Reviewed-by: dholmes, ccheung
This commit is contained in:
parent
ef7a9f8170
commit
646c8aaeec
@ -2947,15 +2947,15 @@ void ClassVerifier::verify_invoke_instructions(
|
||||
_klass, ref_class, method_name, method_sig, true)) {
|
||||
// It's protected access, check if stack object is
|
||||
// assignable to current class.
|
||||
bool is_assignable = current_type().is_assignable_from(
|
||||
stack_object_type, this, true, CHECK_VERIFY(this));
|
||||
if (!is_assignable) {
|
||||
if (ref_class_type.name() == vmSymbols::java_lang_Object()
|
||||
&& stack_object_type.is_array()
|
||||
&& method_name == vmSymbols::clone_name()) {
|
||||
// Special case: arrays pretend to implement public Object
|
||||
// clone().
|
||||
} else {
|
||||
if (ref_class_type.name() == vmSymbols::java_lang_Object()
|
||||
&& stack_object_type.is_array()
|
||||
&& method_name == vmSymbols::clone_name()) {
|
||||
// Special case: arrays pretend to implement public Object
|
||||
// clone().
|
||||
} else {
|
||||
bool is_assignable = current_type().is_assignable_from(
|
||||
stack_object_type, this, true, CHECK_VERIFY(this));
|
||||
if (!is_assignable) {
|
||||
verify_error(ErrorContext::bad_type(bci,
|
||||
current_frame->stack_top_ctx(),
|
||||
TypeOrigin::implicit(current_type())),
|
||||
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test Verifier handling of invoking java/lang/Object::clone() on object arrays.
|
||||
* @bug 8286277
|
||||
* @requires vm.cds
|
||||
* @library /test/lib /test/hotspot/jtreg/runtime/verifier /test/hotspot/jtreg/runtime/cds/appcds/test-classes
|
||||
* @build InvokeCloneValid InvokeCloneInvalid VerifyObjArrayCloneTestApp
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar VerifyObjArrayCloneTestApp
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar tests.jar InvokeCloneValid InvokeCloneInvalid
|
||||
* @run driver VerifyObjArrayCloneTest
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.helpers.ClassFileInstaller;
|
||||
|
||||
public class VerifyObjArrayCloneTest {
|
||||
private static String appJar = ClassFileInstaller.getJarPath("app.jar");
|
||||
private static String testsJar = ClassFileInstaller.getJarPath("tests.jar");
|
||||
private static String mainAppClass = "VerifyObjArrayCloneTestApp";
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
testInAppPath();
|
||||
if (Platform.areCustomLoadersSupportedForCDS()) {
|
||||
testInCustomLoader();
|
||||
}
|
||||
}
|
||||
|
||||
// Try to load InvokeCloneValid and InvokeCloneInvalid from the AppClassLoader
|
||||
static void testInAppPath() throws Exception {
|
||||
String cp = appJar + File.pathSeparator + testsJar;
|
||||
TestCommon.dump(cp, TestCommon.list(mainAppClass,
|
||||
"InvokeCloneValid",
|
||||
"InvokeCloneInvalid"));
|
||||
|
||||
TestCommon.run("-cp", cp, "-Xlog:cds+verification=trace",
|
||||
mainAppClass)
|
||||
.assertNormalExit();
|
||||
}
|
||||
|
||||
// Try to load InvokeCloneValid and InvokeCloneInvalid from a custom class loader
|
||||
static void testInCustomLoader() throws Exception {
|
||||
String cp = appJar;
|
||||
|
||||
String classlist[] = new String[] {
|
||||
mainAppClass,
|
||||
"java/lang/Object id: 1",
|
||||
"InvokeCloneValid id: 2 super: 1 source: " + testsJar,
|
||||
"InvokeCloneInvalid id: 3 super: 1 source: " + testsJar,
|
||||
};
|
||||
|
||||
TestCommon.dump(cp, classlist);
|
||||
TestCommon.run("-cp", cp, "-Xlog:cds+verification=trace",
|
||||
mainAppClass, testsJar)
|
||||
.assertNormalExit();
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test Verifier handling of invoking java/lang/Object::clone() on object arrays.
|
||||
* @bug 8286277
|
||||
* @requires vm.cds
|
||||
* @library /test/lib /test/hotspot/jtreg/runtime/verifier
|
||||
* /test/hotspot/jtreg/runtime/cds/appcds
|
||||
* /test/hotspot/jtreg/runtime/cds/appcds/test-classes
|
||||
* @build sun.hotspot.WhiteBox
|
||||
* @build InvokeCloneValid InvokeCloneInvalid VerifyObjArrayCloneTestApp
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar VerifyObjArrayCloneTestApp
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar tests.jar InvokeCloneValid InvokeCloneInvalid
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
|
||||
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar VerifyObjArrayCloneTest
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import jdk.test.lib.helpers.ClassFileInstaller;
|
||||
|
||||
public class VerifyObjArrayCloneTest extends DynamicArchiveTestBase {
|
||||
private static String appJar = ClassFileInstaller.getJarPath("app.jar");
|
||||
private static String testsJar = ClassFileInstaller.getJarPath("tests.jar");
|
||||
private static String mainAppClass = "VerifyObjArrayCloneTestApp";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
runTest(VerifyObjArrayCloneTest::testInAppPath);
|
||||
runTest(VerifyObjArrayCloneTest::testInCustomLoader);
|
||||
}
|
||||
|
||||
// Try to load InvokeCloneValid and InvokeCloneInvalid from the AppClassLoader
|
||||
private static void testInAppPath() throws Exception {
|
||||
String cp = appJar + File.pathSeparator + testsJar;
|
||||
String topArchiveName = getNewArchiveName("top");
|
||||
dump(topArchiveName,
|
||||
"-cp", cp,
|
||||
mainAppClass)
|
||||
.assertNormalExit();
|
||||
|
||||
run(topArchiveName,
|
||||
"-cp", cp,
|
||||
mainAppClass)
|
||||
.assertNormalExit();
|
||||
}
|
||||
|
||||
// Try to load InvokeCloneValid and InvokeCloneInvalid from a custom class loader
|
||||
private static void testInCustomLoader() throws Exception {
|
||||
String cp = appJar;
|
||||
String topArchiveName = getNewArchiveName("top");
|
||||
dump(topArchiveName,
|
||||
"-cp", cp,
|
||||
"-Xlog:cds+class=debug",
|
||||
mainAppClass, testsJar)
|
||||
.assertNormalExit();
|
||||
|
||||
run(topArchiveName,
|
||||
"-cp", cp,
|
||||
mainAppClass, testsJar)
|
||||
.assertNormalExit();
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
public class VerifyObjArrayCloneTestApp {
|
||||
public static void main(String args[]) throws Exception {
|
||||
ClassLoader appLoader = VerifyObjArrayCloneTestApp.class.getClassLoader();
|
||||
if (args.length == 0) {
|
||||
// Load the test classes from the classpath
|
||||
doTest(appLoader);
|
||||
} else {
|
||||
File f = new File(args[0]);
|
||||
URL[] classLoaderUrls = new URL[] {f.getAbsoluteFile().toURI().toURL()};
|
||||
URLClassLoader customLoader = new URLClassLoader(classLoaderUrls, appLoader);
|
||||
doTest(customLoader);
|
||||
}
|
||||
}
|
||||
|
||||
public static void doTest(ClassLoader loader) throws Exception {
|
||||
try {
|
||||
Class.forName("InvokeCloneValid", /*initialize=*/true, loader);
|
||||
} catch (VerifyError e) {
|
||||
throw new RuntimeException("Unexpected VerifyError", e);
|
||||
}
|
||||
|
||||
try {
|
||||
Class.forName("InvokeCloneInvalid", /*initialize=*/true, loader);
|
||||
throw new RuntimeException("VerifyError expected but not thrown");
|
||||
} catch (VerifyError e) {
|
||||
System.out.println("Expected: " + e);
|
||||
}
|
||||
}
|
||||
}
|
46
test/hotspot/jtreg/runtime/verifier/InvokeClone.java
Normal file
46
test/hotspot/jtreg/runtime/verifier/InvokeClone.java
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test Verifier handling of invoking java/lang/Object::clone() on object arrays.
|
||||
* @bug 8286277
|
||||
* @build InvokeCloneValid InvokeCloneInvalid
|
||||
* @run main/othervm -Xverify InvokeClone
|
||||
*/
|
||||
|
||||
public class InvokeClone {
|
||||
public static void main(String[] args) throws ClassNotFoundException {
|
||||
try {
|
||||
Class.forName("InvokeCloneValid");
|
||||
} catch (VerifyError e) {
|
||||
throw new RuntimeException("Unexpected VerifyError", e);
|
||||
}
|
||||
|
||||
try {
|
||||
Class.forName("InvokeCloneInvalid");
|
||||
throw new RuntimeException("VerifyError expected but not thrown");
|
||||
} catch (VerifyError e) {
|
||||
System.out.println("Expected: " + e);
|
||||
}
|
||||
}
|
||||
}
|
34
test/hotspot/jtreg/runtime/verifier/InvokeCloneInvalid.jasm
Normal file
34
test/hotspot/jtreg/runtime/verifier/InvokeCloneInvalid.jasm
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
super public class InvokeCloneInvalid
|
||||
version 52:0
|
||||
{
|
||||
public static Method test:"(Ljava/lang/String;)V"
|
||||
stack 1 locals 1
|
||||
{
|
||||
aload_0;
|
||||
invokevirtual Method "java/lang/Object".clone:"()Ljava/lang/Object;";
|
||||
return;
|
||||
}
|
||||
}
|
42
test/hotspot/jtreg/runtime/verifier/InvokeCloneValid.jasm
Normal file
42
test/hotspot/jtreg/runtime/verifier/InvokeCloneValid.jasm
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
super public class InvokeCloneValid
|
||||
version 52:0
|
||||
{
|
||||
public static Method test:"([Ljava/lang/Object;)V"
|
||||
stack 1 locals 1
|
||||
{
|
||||
aload_0;
|
||||
invokevirtual Method "java/lang/Object".clone:"()Ljava/lang/Object;";
|
||||
return;
|
||||
}
|
||||
|
||||
public static Method test2:"([Ljava/lang/String;)V"
|
||||
stack 1 locals 1
|
||||
{
|
||||
aload_0;
|
||||
invokevirtual Method "java/lang/Object".clone:"()Ljava/lang/Object;";
|
||||
return;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user