Skip to content
Permalink
Browse files
8255342: Remove non-specified JVM checks on Classes with Record attri…
…butes

Reviewed-by: dholmes, coleenp
  • Loading branch information
Harold Seigel committed Oct 27, 2020
1 parent 7679650 commit 18d9905c40c27305363b9a84a6c9dae956a4e4ea
@@ -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;
@@ -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) {
@@ -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
@@ -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
@@ -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
*/

@@ -37,14 +37,8 @@
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");
}
@@ -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
@@ -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
@@ -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",
@@ -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

1 comment on commit 18d9905

@bridgekeeper

This comment has been minimized.

Copy link

@bridgekeeper bridgekeeper bot commented on 18d9905 Oct 27, 2020

Please sign in to comment.