Reland "Set supported CF version to V15"
This reverts commit fc34eccb08694e5479755b819451d95e4228d29c.
Bug: 141587937
Change-Id: I65a35087c7c50410bcd5d0b17fcf2242c4da826c
diff --git a/src/main/java/com/android/tools/r8/cf/CfVersion.java b/src/main/java/com/android/tools/r8/cf/CfVersion.java
index 7a68742..a69cc03 100644
--- a/src/main/java/com/android/tools/r8/cf/CfVersion.java
+++ b/src/main/java/com/android/tools/r8/cf/CfVersion.java
@@ -23,6 +23,10 @@
public static final CfVersion V9 = new CfVersion(Opcodes.V9);
public static final CfVersion V10 = new CfVersion(Opcodes.V10);
public static final CfVersion V11 = new CfVersion(Opcodes.V11);
+ public static final CfVersion V12 = new CfVersion(Opcodes.V12);
+ public static final CfVersion V13 = new CfVersion(Opcodes.V13);
+ public static final CfVersion V14 = new CfVersion(Opcodes.V14);
+ public static final CfVersion V15 = new CfVersion(Opcodes.V15);
private final int version;
diff --git a/src/main/java/com/android/tools/r8/errors/ExperimentalClassFileVersionDiagnostic.java b/src/main/java/com/android/tools/r8/errors/ExperimentalClassFileVersionDiagnostic.java
new file mode 100644
index 0000000..953afb2
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/errors/ExperimentalClassFileVersionDiagnostic.java
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.errors;
+
+import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.position.Position;
+
+public class ExperimentalClassFileVersionDiagnostic implements Diagnostic {
+
+ private final String message;
+ private final Origin origin;
+
+ public ExperimentalClassFileVersionDiagnostic(Origin origin, String message) {
+ this.origin = origin;
+ this.message = message;
+ }
+
+ @Override
+ public Origin getOrigin() {
+ return origin;
+ }
+
+ @Override
+ public Position getPosition() {
+ return Position.UNKNOWN;
+ }
+
+ @Override
+ public String getDiagnosticMessage() {
+ return message;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index 0902a45..fabdde7 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -57,12 +57,12 @@
import java.util.function.Consumer;
import java.util.zip.CRC32;
import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.RecordComponentVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.TypePath;
@@ -300,6 +300,17 @@
}
@Override
+ public RecordComponentVisitor visitRecordComponent(
+ String name, String descriptor, String signature) {
+ throw new CompilationError("Records are not supported", origin);
+ }
+
+ @Override
+ public void visitPermittedSubclass(String permittedSubclass) {
+ throw new CompilationError("Sealed classes are not supported", origin);
+ }
+
+ @Override
public void visit(
int rawVersion,
int access,
@@ -311,6 +322,9 @@
if (InternalOptions.SUPPORTED_CF_VERSION.isLessThan(version)) {
throw new CompilationError("Unsupported class file version: " + version, origin);
}
+ if (version.isGreaterThanOrEqualTo(InternalOptions.EXPERIMENTAL_CF_VERSION)) {
+ application.options.warningExperimentalClassFileVersion(origin);
+ }
this.deprecated = AsmUtils.isDeprecated(access);
accessFlags = ClassAccessFlags.fromCfAccessFlags(cleanAccessFlags(access));
type = application.getTypeFromName(name);
@@ -400,11 +414,6 @@
}
@Override
- public void visitAttribute(Attribute attr) {
- // Unknown attribute must only be ignored
- }
-
- @Override
public void visitEnd() {
if (defaultAnnotations != null) {
addAnnotation(DexAnnotation.createAnnotationDefaultAnnotation(
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 6c0cc5b..175a39e 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -21,6 +21,7 @@
import com.android.tools.r8.dex.Marker.Backend;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.errors.ExperimentalClassFileVersionDiagnostic;
import com.android.tools.r8.errors.IncompleteNestNestDesugarDiagnosic;
import com.android.tools.r8.errors.InterfaceDesugarMissingTypeDiagnostic;
import com.android.tools.r8.errors.InvalidDebugInfoException;
@@ -108,11 +109,13 @@
ON
}
- public static final CfVersion SUPPORTED_CF_VERSION = CfVersion.V11;
+ public static final CfVersion SUPPORTED_CF_VERSION = CfVersion.V15;
+ public static final CfVersion EXPERIMENTAL_CF_VERSION = CfVersion.V12;
+
public static final int SUPPORTED_DEX_VERSION =
AndroidApiLevel.LATEST.getDexVersion().getIntValue();
- public static final int ASM_VERSION = Opcodes.ASM7;
+ public static final int ASM_VERSION = Opcodes.ASM9;
public final DexItemFactory itemFactory;
@@ -1044,6 +1047,23 @@
reporter.warning(new StringDiagnostic(message.toString(), origin));
}
+ private final Box<Boolean> reportedExperimentClassFileVersion = new Box<>(false);
+
+ public void warningExperimentalClassFileVersion(Origin origin) {
+ synchronized (reportedExperimentClassFileVersion) {
+ if (reportedExperimentClassFileVersion.get()) {
+ return;
+ }
+ reportedExperimentClassFileVersion.set(true);
+ reporter.warning(
+ new ExperimentalClassFileVersionDiagnostic(
+ origin,
+ "One or more classes has class file version >= "
+ + EXPERIMENTAL_CF_VERSION.major()
+ + " which is not officially supported."));
+ }
+ }
+
public boolean printWarnings() {
boolean printed = false;
boolean printOutdatedToolchain = false;
diff --git a/src/test/java/com/android/tools/r8/TestParametersBuilder.java b/src/test/java/com/android/tools/r8/TestParametersBuilder.java
index f93d6d6..9b84425 100644
--- a/src/test/java/com/android/tools/r8/TestParametersBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestParametersBuilder.java
@@ -19,10 +19,6 @@
public class TestParametersBuilder {
- // Static computation of VMs configured as available by the testing invocation.
- private static final List<TestRuntime> availableRuntimes =
- getAvailableRuntimes().collect(Collectors.toList());
-
// Predicate describing which test parameters are applicable to the test.
// Built via the methods found below. Defaults to no applicable parameters, i.e., the emtpy set.
private Predicate<TestParameters> filter = param -> false;
@@ -154,6 +150,7 @@
private Predicate<AndroidApiLevel> apiLevelFilter = param -> false;
private List<AndroidApiLevel> explicitApiLevels = new ArrayList<>();
+ private List<TestRuntime> customRuntimes = new ArrayList<>();
private TestParametersBuilder withApiFilter(Predicate<AndroidApiLevel> filter) {
enableApiLevels = true;
@@ -195,13 +192,23 @@
return withApiFilter(api -> api.getLevel() < endExclusive.getLevel());
}
+ public TestParametersBuilder withCustomRuntime(TestRuntime runtime) {
+ assert getUnfilteredAvailableRuntimes().noneMatch(r -> r == runtime);
+ customRuntimes.add(runtime);
+ return this;
+ }
+
public TestParametersCollection build() {
assert !enableApiLevels || enableApiLevelsForCf || hasDexRuntimeFilter;
- return new TestParametersCollection(
+ List<TestParameters> availableParameters =
getAvailableRuntimes()
.flatMap(this::createParameters)
.filter(filter)
- .collect(Collectors.toList()));
+ .collect(Collectors.toList());
+ List<TestParameters> customParameters =
+ customRuntimes.stream().flatMap(this::createParameters).collect(Collectors.toList());
+ availableParameters.addAll(customParameters);
+ return new TestParametersCollection(availableParameters);
}
public Stream<TestParameters> createParameters(TestRuntime runtime) {
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordsAttributeTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordsAttributeTest.java
index 723dfe6..831c426 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordsAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordsAttributeTest.java
@@ -7,12 +7,13 @@
import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime;
+import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.examples.jdk15.Records;
import com.android.tools.r8.utils.AndroidApiLevel;
import java.util.List;
@@ -25,23 +26,29 @@
public class RecordsAttributeTest extends TestBase {
private final Backend backend;
+ private final TestParameters parameters;
@Parameters(name = "{0}")
public static List<Object[]> data() {
- return buildParameters(getTestParameters().withNoneRuntime().build(), Backend.values());
+ // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk15).
+ return buildParameters(
+ getTestParameters().withCustomRuntime(CfRuntime.getCheckedInJdk15()).build(),
+ Backend.values());
}
public RecordsAttributeTest(TestParameters parameters, Backend backend) {
+ this.parameters = parameters;
this.backend = backend;
}
@Test
public void testJvm() throws Exception {
+ assumeFalse(parameters.isNoneRuntime());
assumeTrue(backend == Backend.CF);
testForJvm()
.addRunClasspathFiles(Records.jar())
.addVmArguments("--enable-preview")
- .run(TestRuntime.getCheckedInJdk15(), Records.Main.typeName())
+ .run(parameters.getRuntime(), Records.Main.typeName())
.assertSuccessWithOutputLines("Jane Doe", "42");
}
@@ -56,7 +63,7 @@
.compileWithExpectedDiagnostics(
diagnostics -> {
diagnostics.assertErrorThatMatches(
- diagnosticMessage(containsString("Unsupported class file version: 59")));
+ diagnosticMessage(containsString("Records are not supported")));
});
});
}
@@ -73,7 +80,7 @@
.compileWithExpectedDiagnostics(
diagnostics -> {
diagnostics.assertErrorThatMatches(
- diagnosticMessage(containsString("Unsupported class file version: 59")));
+ diagnosticMessage(containsString("Records are not supported")));
});
});
}
diff --git a/src/test/java/com/android/tools/r8/desugar/sealed/SealedAttributeTest.java b/src/test/java/com/android/tools/r8/desugar/sealed/SealedAttributeTest.java
index 8aa79eb..48b29e7 100644
--- a/src/test/java/com/android/tools/r8/desugar/sealed/SealedAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/sealed/SealedAttributeTest.java
@@ -28,7 +28,10 @@
@Parameters(name = "{0}")
public static List<Object[]> data() {
- return buildParameters(getTestParameters().withNoneRuntime().build(), Backend.values());
+ // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk15).
+ return buildParameters(
+ getTestParameters().withCustomRuntime(TestRuntime.getCheckedInJdk15()).build(),
+ Backend.values());
}
public SealedAttributeTest(TestParameters parameters, Backend backend) {
@@ -56,7 +59,7 @@
.compileWithExpectedDiagnostics(
diagnostics -> {
diagnostics.assertErrorThatMatches(
- diagnosticMessage(containsString("Unsupported class file version: 59")));
+ diagnosticMessage(containsString("Sealed classes are not supported")));
});
});
}
@@ -73,7 +76,7 @@
.compileWithExpectedDiagnostics(
diagnostics -> {
diagnostics.assertErrorThatMatches(
- diagnosticMessage(containsString("Unsupported class file version: 59")));
+ diagnosticMessage(containsString("Sealed classes are not supported")));
});
});
}
diff --git a/tools/test.py b/tools/test.py
index 0c70124..cf14685 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -156,6 +156,11 @@
'--print-obfuscated-stacktraces', '--print_obfuscated_stacktraces',
default=False, action='store_true',
help='Print the obfuscated stacktraces')
+ result.add_option(
+ '--debug-agent', '--debug_agent',
+ help='Enable Java debug agent and suspend compilation (default disabled)',
+ default=False,
+ action='store_true')
return result.parse_args()
def archive_failures():
@@ -253,6 +258,8 @@
if options.worktree:
gradle_args.append('-g=' + os.path.join(utils.REPO_ROOT, ".gradle_user_home"))
gradle_args.append('--no-daemon')
+ if options.debug_agent:
+ gradle_args.append('--no-daemon')
# Build an R8 with dependencies for bootstrapping tests before adding test sources.
gradle_args.append('r8WithDeps')
@@ -263,6 +270,8 @@
# Add Gradle tasks
gradle_args.append('cleanTest')
gradle_args.append('test')
+ if options.debug_agent:
+ gradle_args.append('--debug-jvm')
if options.fail_fast:
gradle_args.append('--fail-fast')
if options.failed: