Skip to content

Commit

Permalink
8255342: Remove non-specified JVM checks on Classes with Record attri…
Browse files Browse the repository at this point in the history
…butes

Reviewed-by: dholmes, coleenp
  • Loading branch information
Harold Seigel committed Oct 27, 2020
1 parent 7679650 commit 18d9905
Show file tree
Hide file tree
Showing 6 changed files with 353 additions and 43 deletions.
22 changes: 4 additions & 18 deletions src/hotspot/share/classfile/classFileParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3900,19 +3900,11 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
_nest_host = class_info_index;
} else if (_major_version >= JAVA_14_VERSION) {
if (tag == vmSymbols::tag_record()) {
// Skip over Record attribute if not supported or if super class is
// not java.lang.Record.
if (supports_records() &&
cp->klass_name_at(_super_class_index) == vmSymbols::java_lang_Record()) {
if (supports_records()) { // Skip over Record attribute if not supported.
if (parsed_record_attribute) {
classfile_parse_error("Multiple Record attributes in class file %s", THREAD);
return;
}
// Check that class is final and not abstract.
if (!_access_flags.is_final() || _access_flags.is_abstract()) {
classfile_parse_error("Record attribute in non-final or abstract class file %s", THREAD);
return;
}
parsed_record_attribute = true;
record_attribute_start = cfs->current();
record_attribute_length = attribute_length;
Expand All @@ -3922,15 +3914,9 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
// --enable-preview wasn't specified then a java.lang.UnsupportedClassVersionError
// exception would have been thrown.
ResourceMark rm(THREAD);
if (supports_records()) {
log_info(class, record)(
"Ignoring Record attribute in class %s because super type is not java.lang.Record",
_class_name->as_C_string());
} else {
log_info(class, record)(
"Ignoring Record attribute in class %s because class file version is not %d.65535",
_class_name->as_C_string(), JVM_CLASSFILE_MAJOR_VERSION);
}
log_info(class, record)(
"Ignoring Record attribute in class %s because class file version is not %d.65535",
_class_name->as_C_string(), JVM_CLASSFILE_MAJOR_VERSION);
}
cfs->skip_u1(attribute_length, CHECK);
} else if (_major_version >= JAVA_15_VERSION) {
Expand Down
6 changes: 3 additions & 3 deletions test/hotspot/jtreg/runtime/records/abstractRecord.jcod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, 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
Expand All @@ -24,8 +24,8 @@
// This test was generated from this source and then modified:
// record recordNames(int x, String y) {}

// This test is a Record marked as abstract. It should result in a
// ClassFormatError exception.
// This test is a Record marked as abstract. Loading this class should
// not cause a ClassFormatError exception.
class abstractRecord {
0xCAFEBABE;
65535; // minor version
Expand Down
10 changes: 2 additions & 8 deletions test/hotspot/jtreg/runtime/records/ignoreRecordAttribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* @test
* @summary test logging of reasons for ignoring Record attribute
* @library /test/lib
* @compile superNotJLRecord.jcod recordIgnoredVersion.jcod
* @compile recordIgnoredVersion.jcod
* @run driver ignoreRecordAttribute
*/

Expand All @@ -37,14 +37,8 @@ public class ignoreRecordAttribute {
public static void main(String[] args) throws Exception {
String MAJOR_VERSION = Integer.toString(44 + Runtime.version().feature());
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--enable-preview",
"-Xlog:class+record", "-Xshare:off", "superNotJLRecord");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("Ignoring Record attribute");
output.shouldContain("because super type is not java.lang.Record");

pb = ProcessTools.createJavaProcessBuilder("--enable-preview",
"-Xlog:class+record", "-Xshare:off", "recordIgnoredVersion");
output = new OutputAnalyzer(pb.start());
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("Ignoring Record attribute");
output.shouldContain("because class file version is not " + MAJOR_VERSION + ".65535");
}
Expand Down
4 changes: 2 additions & 2 deletions test/hotspot/jtreg/runtime/records/notFinalRecord.jcod
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
// This test was generated from this source and then modified:
// record recordNames(int x, String y) {}

// This test is a Record but not marked final. It should result in a
// ClassFormatError exception.
// This test is a Record but not marked final. Loading this class should
// not cause a ClassFormatError exception.
class notFinalRecord {
0xCAFEBABE;
65535; // minor version
Expand Down
23 changes: 13 additions & 10 deletions test/hotspot/jtreg/runtime/records/recordAttributeTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, 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
Expand Down Expand Up @@ -54,13 +54,11 @@ public static void main(String... args) throws Throwable {
runTest("twoRecordAttributes",
"Multiple Record attributes in class");

// Test loading a Record type marked abstract. This should throw ClassFormatError.
runTest("abstractRecord",
"Record attribute in non-final or abstract class");
// Test loading a Record type marked abstract. This should not throw ClassFormatError.
Class abstractClass = Class.forName("abstractRecord");

// Test loading a Record type that is not final. This should throw ClassFormatError.
runTest("notFinalRecord",
"Record attribute in non-final or abstract class");
// Test loading a Record type that is not final. This should not throw ClassFormatError.
Class notFinalClass = Class.forName("notFinalRecord");

// Test loading a Record type that is badly formed. This should throw ClassFormatError.
runTest("badRecordAttribute",
Expand All @@ -73,8 +71,13 @@ public static void main(String... args) throws Throwable {
// badly formed Record attribute. No exception should be thrown.
Class newClass = Class.forName("oldRecordAttribute");

// Test that loading a class whose super class is not java.lang.Record
// ignores a badly formed Record attribute. No exception should be thrown.
newClass = Class.forName("superNotJLRecord");
// Test that loading a class containing an ill-formed Record attribute causes a
// ClassFormatError exception even though its super class is not java.lang.Record.
runTest("superNotJLRecord", "Truncated class file");

// Test that loading a class that contains a properly formed Record attribute
// does not cause a ClassFormatError exception even though its super class is not
// java.lang.Record.
Class superNoJLRClass = Class.forName("superNotJLRecordOK");
}
}
Loading

0 comments on commit 18d9905

Please sign in to comment.