Merge "Add support for sharding tests"
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
index ff330e1..9dff882 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
@@ -581,7 +581,8 @@
// target.
return;
}
- if (!dexItemFactory.npeType.isSubtypeOf(guard, appView.appInfo())) {
+ if (guard != dexItemFactory.catchAllType
+ && !dexItemFactory.npeType.isSubtypeOf(guard, appView.appInfo())) {
// TODO(christofferqa): Consider updating previous dominator tree instead of
// rebuilding it from scratch.
DominatorTree dominatorTree = new DominatorTree(code, MAY_HAVE_UNREACHABLE_BLOCKS);
diff --git a/src/test/java/com/android/tools/r8/JctfTestSpecifications.java b/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
index a35ce71..34955b6 100644
--- a/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
+++ b/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
@@ -894,7 +894,7 @@
"lang.String.getBytesLjava_lang_String.String_getBytes_A14",
match(artRuntimesUpTo(Runtime.ART_V7_0_0)))
.put("lang.String.splitLjava_lang_String.String_split_A01", any())
- .put("lang.String.getBytesII_BI.String_getBytes_A03", any())
+ .put("lang.String.getBytesII_BI.String_getBytes_A03", anyDexVm())
.put("lang.String.getBytesII_BI.String_getBytes_A02", anyDexVm())
.put("lang.String.toLowerCaseLjava_util_Locale.String_toLowerCase_A01", any())
.put("lang.String.Constructor_BIILjava_nio_charset_Charset.String_Constructor_A01", any())
@@ -1690,6 +1690,54 @@
"lang.String.replaceAllLjava_lang_StringLjava_lang_String.String_replaceAll_A01",
cf())
.put("lang.System.inheritedChannel.System_inheritedChannel_A01", cf())
+ // TODO(b/124842490): Failing with change to JDK 9 for the classfile backend.
+ .put("lang.Character.isSpaceCharC.Character_isSpaceChar_A01", cf())
+ .put("lang.Character.isSpaceCharI.Character_isSpaceChar_A01", cf())
+ .put("lang.Character.isWhitespaceI.Character_isWhitespace_A01", cf())
+ .put("lang.Class.getConstructors.Class_getConstructors_A01", cf())
+ .put("lang.Class.getPackage.Class_getPackage_A01", cf())
+ .put(
+ "lang.Class.getResourceAsStreamLjava_lang_String.Class_getResourceAsStream_A01", cf())
+ .put("lang.Class.getResourceLjava_lang_String.Class_getResource_A01", cf())
+ .put(
+ "lang.ClassLoader.defineClassLjava_lang_StringLjava_nio_ByteBufferLjava_security_ProtectionDomain.ClassLoader_defineClass_A01",
+ cf())
+ .put(
+ "lang.ClassLoader.defineClassLjava_lang_String_BII.ClassLoader_defineClass_A01", cf())
+ .put(
+ "lang.ClassLoader.defineClassLjava_lang_String_BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A01",
+ cf())
+ .put("lang.ClassLoader.defineClass_BII.ClassLoader_defineClass_A01", cf())
+ .put(
+ "lang.ClassLoader.definePackageLjava_lang_String6Ljava_net_URL.ClassLoader_definePackage_A03",
+ cf())
+ .put("lang.ClassLoader.getPackages.ClassLoader_getPackages_A01", cf())
+ .put("lang.Package.getImplementationVersion.Package_getImplementationVersion_A01", cf())
+ .put(
+ "lang.SecurityManager.checkAwtEventQueueAccess.SecurityManager_checkAwtEventQueueAccess_A01",
+ cf())
+ .put(
+ "lang.SecurityManager.checkSystemClipboardAccess.SecurityManager_checkSystemClipboardAccess_A01",
+ cf())
+ .put(
+ "lang.SecurityManager.checkTopLevelWindowLjava_lang_Object.SecurityManager_checkTopLevelWindow_A01",
+ cf())
+ .put("lang.StrictMath.toDegreesD.StrictMath_toDegrees_A01", cf())
+ .put("lang.StrictMath.toRadiansD.StrictMath_toRadians_A01", cf())
+ .put("lang.String.matchesLjava_lang_String.String_matches_A01", cf())
+ .put("lang.StringBuffer.append_CII.StringBuffer_append_A03", cf())
+ .put("lang.System.getProperties.System_getProperties_A02", cf())
+ .put("lang.System.getPropertyLjava_lang_String.System_getProperty_A02", cf())
+ .put(
+ "lang.System.getPropertyLjava_lang_StringLjava_lang_String.System_getProperty_A02",
+ cf())
+ .put("lang.Throwable.serialization.Throwable_serialization_A01", cf())
+ .put("lang.ref.ReferenceQueue.poll.ReferenceQueue_poll_A01", cf())
+ .put("lang.ref.ReferenceQueue.remove.ReferenceQueue_remove_A01", cf())
+ .put("lang.ref.ReferenceQueue.removeJ.ReferenceQueue_remove_A01", cf())
+ .put("lang.reflect.Constructor.toGenericString.Constructor_toGenericString_A01", cf())
+ .put("lang.reflect.Field.getGenericType.Field_getGenericType_A01", cf())
+ .put("lang.reflect.Field.toGenericString.Field_toGenericString_A01", cf())
.build(); // end of failuresToTriage
public static final Multimap<String, TestCondition> flakyWhenRun =
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/SynchronizedMethodTest.java b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/SynchronizedMethodTest.java
new file mode 100644
index 0000000..f082098
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/SynchronizedMethodTest.java
@@ -0,0 +1,102 @@
+// Copyright (c) 2019, 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.ir.optimize.uninstantiatedtypes;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.Test;
+
+public class SynchronizedMethodTest extends TestBase {
+
+ @Test
+ public void test() throws Exception {
+ String expectedOutput = StringUtils.lines("In A.m()", "Got NullPointerException");
+ CodeInspector inspector =
+ testForR8(Backend.DEX)
+ .addInnerClasses(SynchronizedMethodTest.class)
+ .addKeepMainRule(TestClass.class)
+ .enableInliningAnnotations()
+ .enableMergeAnnotations()
+ .run(TestClass.class)
+ .assertSuccessWithOutput(expectedOutput)
+ .inspector();
+
+ ClassSubject clazz = inspector.clazz(A.class);
+ MethodSubject method = clazz.uniqueMethodWithName("m");
+
+ // The invoke on the uninstantiated turns into a "throw null", and the synchronized method
+ // already have a throw instruction in the catch all handler ensuring monitor exit is called.
+ List<InstructionSubject> throwInstructions =
+ method
+ .streamInstructions()
+ .filter(InstructionSubject::isThrow)
+ .collect(Collectors.toList());
+ assertEquals(2, throwInstructions.size());
+
+ // The inserted "throw null" should still be covered by the catch all to ensure monitor exit
+ // is called.
+ List<InstructionSubject> catchAllCoveredInstructions = new ArrayList<>();
+ method.iterateTryCatches().forEachRemaining(tryCatchSubject -> {
+ if (tryCatchSubject.hasCatchAll()) {
+ catchAllCoveredInstructions.addAll(
+ throwInstructions
+ .stream()
+ .filter(
+ throwInstruction ->
+ tryCatchSubject.getRange().includes(throwInstruction.getOffset(method)))
+ .collect(Collectors.toList()));
+ }
+ });
+ assertEquals(1, catchAllCoveredInstructions.size());
+ assertSame(throwInstructions.get(0), catchAllCoveredInstructions.get(0));
+ }
+
+ static class TestClass {
+
+ public static void main(String[] args) {
+ try {
+ test(new A());
+ } catch (NullPointerException e) {
+ System.out.println("Got NullPointerException");
+ }
+ }
+
+ @NeverInline
+ private static void test(A obj) {
+ obj.m();
+ }
+ }
+
+ static class A {
+
+ @NeverInline
+ static Uninstantiated createUninstantiated() {
+ return null;
+ }
+
+ @NeverInline
+ public synchronized void m() {
+ System.out.println("In A.m()");
+ A.createUninstantiated().m();
+ }
+ }
+
+ static class Uninstantiated {
+ public void m() {
+ System.out.println("In Uninstantiated.m()");
+ }
+ }
+}