Merge "Revert "Assert that definitionFor is only called on non-null class types.""
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfoWithSubtyping.java b/src/main/java/com/android/tools/r8/graph/AppInfoWithSubtyping.java
index e415b0f..a45064e 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfoWithSubtyping.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfoWithSubtyping.java
@@ -119,10 +119,8 @@
// For mapping invoke virtual instruction to target methods.
public Set<DexEncodedMethod> lookupVirtualTargets(DexMethod method) {
- if (method.holder.isArrayType()) {
- assert method.name == dexItemFactory.cloneMethodName;
- return null;
- }
+ Set<DexEncodedMethod> result = new HashSet<>();
+ // First add the target for receiver type method.type.
DexClass root = definitionFor(method.holder);
if (root == null) {
// type specified in method does not have a materialized class.
@@ -133,8 +131,6 @@
// This will fail at runtime.
return null;
}
- // First add the target for receiver type method.type.
- Set<DexEncodedMethod> result = new HashSet<>();
topTargets.forEachTarget(result::add);
// Add all matching targets from the subclass hierarchy.
for (DexType type : subtypes(method.holder)) {
diff --git a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
index 1e125d9..09094aa 100644
--- a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
@@ -45,7 +45,6 @@
@Override
public DexClass definitionFor(DexType type) {
- assert type.isClassType() : "Cannot lookup definition for type: " + type;
DexClass result = programClasses.get(type);
if (result == null) {
result = libraryClasses.get(type);
diff --git a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
index b236428..6dea825 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
@@ -42,7 +42,9 @@
@Override
public DexClass definitionFor(DexType type) {
- assert type.isClassType() : "Cannot lookup definition for type: " + type;
+ if (type == null) {
+ return null;
+ }
DexClass clazz = programClasses.get(type);
if (clazz == null && classpathClasses != null) {
clazz = classpathClasses.get(type);
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/TypeChecker.java b/src/main/java/com/android/tools/r8/ir/analysis/TypeChecker.java
index 75a9726..53a6245 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/TypeChecker.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/TypeChecker.java
@@ -78,7 +78,7 @@
return true;
}
- if (fieldType.isClassType() && valueType.isReference()) {
+ if (valueType.isReference()) {
// Interface types are treated like Object according to the JVM spec.
// https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.10.1.2-100
DexClass clazz = appInfo.definitionFor(instruction.getField().type);
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstClass.java b/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
index 7610f9c..bd57f29 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
@@ -91,9 +91,6 @@
// A const-class instruction can be dead code only if the resulting program is known to contain
// the class mentioned.
DexType baseType = clazz.toBaseType(appInfo.dexItemFactory);
- if (baseType.isPrimitiveType()) {
- return true;
- }
DexClass holder = appInfo.definitionFor(baseType);
return holder != null && holder.isProgramClass();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 1eae24e..7758d83 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -2156,9 +2156,6 @@
private boolean isTypeInaccessibleInCurrentContext(DexType type, DexEncodedMethod context) {
DexType baseType = type.toBaseType(appInfo.dexItemFactory);
- if (baseType.isPrimitiveType()) {
- return false;
- }
DexClass clazz = definitionFor(baseType);
if (clazz == null) {
// Conservatively say yes.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index cdf37c4..7375303 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -113,9 +113,6 @@
eligibleClass =
root.isNewInstance() ? root.asNewInstance().clazz : root.asStaticGet().getField().type;
- if (!eligibleClass.isClassType()) {
- return false;
- }
eligibleClassDefinition = appInfo.definitionFor(eligibleClass);
if (eligibleClassDefinition == null && lambdaRewriter != null) {
// Check if the class is synthesized for a desugared lambda
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 8560ba7..adc6979 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -2414,10 +2414,6 @@
// https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html#jvms-6.5.invokevirtual
assert method != null;
assert refinedReceiverType.isSubtypeOf(method.holder, this);
- if (method.holder.isArrayType()) {
- assert method.name == dexItemFactory.cloneMethodName;
- return null;
- }
DexClass holder = definitionFor(method.holder);
if (holder == null || holder.isLibraryClass() || holder.isInterface()) {
return null;
diff --git a/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java b/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java
index 71b3d53..543dcc4 100644
--- a/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java
+++ b/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.UseRegistry;
+import com.google.common.collect.ImmutableSet;
import java.util.Set;
import java.util.function.Consumer;
@@ -60,23 +61,35 @@
boolean value = false;
}
+ public static boolean hasReferencesOutside(
+ AppInfoWithSubtyping appInfo, DexProgramClass clazz, Set<DexType> types) {
+ BooleanBox result = new BooleanBox();
+
+ new MainDexDirectReferenceTracer(appInfo, type -> {
+ if (!types.contains(type)) {
+ DexClass cls = appInfo.definitionFor(type);
+ if (cls != null && !cls.isLibraryClass()) {
+ result.value = true;
+ }
+ }
+ }).run(ImmutableSet.of(clazz.type));
+
+ return result.value;
+ }
+
public static boolean hasReferencesOutsideFromCode(
AppInfoWithSubtyping appInfo, DexEncodedMethod method, Set<DexType> classes) {
BooleanBox result = new BooleanBox();
- new MainDexDirectReferenceTracer(
- appInfo,
- type -> {
- DexType baseType = type.toBaseType(appInfo.dexItemFactory);
- if (baseType.isClassType() && !classes.contains(baseType)) {
- DexClass cls = appInfo.definitionFor(baseType);
- if (cls != null && !cls.isLibraryClass()) {
- result.value = true;
- }
- }
- })
- .runOnCode(method);
+ new MainDexDirectReferenceTracer(appInfo, type -> {
+ if (!classes.contains(type)) {
+ DexClass cls = appInfo.definitionFor(type);
+ if (cls != null && !cls.isLibraryClass()) {
+ result.value = true;
+ }
+ }
+ }).runOnCode(method);
return result.value;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
index ff196e3..898d06c 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
@@ -843,9 +843,6 @@
}
private void includeDescriptor(DexDefinition item, DexType type, ProguardKeepRule context) {
- if (type.isVoidType()) {
- return;
- }
if (type.isArrayType()) {
type = type.toBaseType(application.dexItemFactory);
}
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 15dcafa..d793e3b 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -336,16 +336,15 @@
}
private void markTypeAsPinned(DexType type, AbortReason reason) {
- DexType baseType = type.toBaseType(appInfo.dexItemFactory);
- if (!baseType.isClassType() || appInfo.isPinned(baseType)) {
+ if (appInfo.isPinned(type)) {
// We check for the case where the type is pinned according to appInfo.isPinned,
// so we only need to add it here if it is not the case.
return;
}
- DexClass clazz = appInfo.definitionFor(baseType);
+ DexClass clazz = appInfo.definitionFor(type);
if (clazz != null && clazz.isProgramClass()) {
- boolean changed = pinnedTypes.add(baseType);
+ boolean changed = pinnedTypes.add(type);
if (Log.ENABLED) {
if (changed && isMergeCandidate(clazz.asProgramClass(), ImmutableSet.of())) {
@@ -744,6 +743,10 @@
return false;
}
+ private boolean hasReferencesOutside(DexProgramClass clazz, Set<DexType> types) {
+ return MainDexDirectReferenceTracer.hasReferencesOutside(appInfo, clazz, types);
+ }
+
private void mergeClassIfPossible(DexProgramClass clazz) {
if (!mergeCandidates.contains(clazz)) {
return;
diff --git a/src/test/examples/classmerging/PinnedArrayParameterTypesTest.java b/src/test/examples/classmerging/PinnedArrayParameterTypesTest.java
deleted file mode 100644
index 4a8b5be..0000000
--- a/src/test/examples/classmerging/PinnedArrayParameterTypesTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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 classmerging;
-
-import java.lang.reflect.Method;
-
-public class PinnedArrayParameterTypesTest {
-
- public static void main(String[] args) throws Exception {
- for (Method method : TestClass.class.getMethods()) {
- if (method.getName().equals("method")) {
- Class<?> parameterType = method.getParameterTypes()[0];
-
- // Should print classmerging.PinnedArrayParameterTypesTest$Interface when
- // -keepparameternames is used.
- System.out.println(parameterType.getName());
-
- method.invoke(null, new Object[]{ new InterfaceImpl[]{ new InterfaceImpl() } });
- break;
- }
- }
- }
-
- public interface Interface {
-
- void foo();
- }
-
- public static class InterfaceImpl implements Interface {
-
- @Override
- public void foo() {
- System.out.println("In InterfaceImpl.foo()");
- }
- }
-
- public static class TestClass {
-
- // This method has been kept explicitly by a keep rule. Therefore, since -keepparameternames is
- // used, Interface must not be merged into InterfaceImpl.
- public static void method(Interface[] obj) {
- obj[0].foo();
- }
- }
-}
diff --git a/src/test/examples/classmerging/keep-rules.txt b/src/test/examples/classmerging/keep-rules.txt
index c75058d..e3e0006 100644
--- a/src/test/examples/classmerging/keep-rules.txt
+++ b/src/test/examples/classmerging/keep-rules.txt
@@ -43,12 +43,6 @@
-keep public class classmerging.PinnedParameterTypesTest$TestClass {
public static void method(...);
}
--keep public class classmerging.PinnedArrayParameterTypesTest {
- public static void main(...);
-}
--keep public class classmerging.PinnedArrayParameterTypesTest$TestClass {
- public static void method(...);
-}
-keep public class classmerging.ProguardFieldMapTest {
public static void main(...);
}
diff --git a/src/test/java/com/android/tools/r8/D8TestBuilder.java b/src/test/java/com/android/tools/r8/D8TestBuilder.java
index 37e4dec..88d077b 100644
--- a/src/test/java/com/android/tools/r8/D8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/D8TestBuilder.java
@@ -3,18 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
-import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer;
import com.android.tools.r8.D8Command.Builder;
import com.android.tools.r8.TestBase.Backend;
import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
-import java.io.IOException;
import java.nio.file.Path;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -22,9 +17,6 @@
extends TestCompilerBuilder<
D8Command, Builder, D8TestCompileResult, D8TestRunResult, D8TestBuilder> {
- // Consider an in-order collection of both class and files on the classpath.
- private List<Class<?>> classpathClasses = new ArrayList<>();
-
private D8TestBuilder(TestState state, Builder builder) {
super(state, builder, Backend.DEX);
}
@@ -42,29 +34,6 @@
D8TestCompileResult internalCompile(
Builder builder, Consumer<InternalOptions> optionsConsumer, Supplier<AndroidApp> app)
throws CompilationFailedException {
- if (!classpathClasses.isEmpty()) {
- Path cp;
- try {
- cp = getState().getNewTempFolder().resolve("cp.jar");
- } catch (IOException e) {
- throw builder.getReporter().fatalError("Failed to create temp file for classpath archive");
- }
- ArchiveConsumer archiveConsumer = new ArchiveConsumer(cp);
- for (Class<?> classpathClass : classpathClasses) {
- try {
- archiveConsumer.accept(
- ByteDataView.of(ToolHelper.getClassAsBytes(classpathClass)),
- DescriptorUtils.javaTypeToDescriptor(classpathClass.getTypeName()),
- builder.getReporter());
- } catch (IOException e) {
- builder
- .getReporter()
- .error("Failed to read bytes for classpath class: " + classpathClass.getTypeName());
- }
- }
- archiveConsumer.finished(builder.getReporter());
- builder.addClasspathFiles(cp);
- }
ToolHelper.runD8(builder, optionsConsumer);
return new D8TestCompileResult(getState(), app.get());
}
@@ -74,8 +43,7 @@
}
public D8TestBuilder addClasspathClasses(Collection<Class<?>> classes) {
- classpathClasses.addAll(classes);
- return self();
+ return addClasspathFiles(getFilesForClasses(classes));
}
public D8TestBuilder addClasspathFiles(Path... files) {
diff --git a/src/test/java/com/android/tools/r8/RegressionForPrimitiveDefinitionForLookup.java b/src/test/java/com/android/tools/r8/RegressionForPrimitiveDefinitionForLookup.java
deleted file mode 100644
index b43bb8b..0000000
--- a/src/test/java/com/android/tools/r8/RegressionForPrimitiveDefinitionForLookup.java
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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;
-
-import com.android.tools.r8.utils.StringUtils;
-import org.junit.Test;
-
-class Tester {
- public int foo() {
- float[][][] fs = new float[1][2][3];
- return fs.length;
- }
-
- public static void main(String[] args) {
- System.out.println(new Tester().foo());
- }
-}
-
-// The DirectoryClasspathProvider asserts lookups are reference types which witnessed the issue.
-public class RegressionForPrimitiveDefinitionForLookup extends TestBase {
-
- public final Class<Tester> CLASS = Tester.class;
- public String EXPECTED = StringUtils.lines("1");
-
- @Test
- public void testWithArchiveClasspath() throws Exception {
- testForD8()
- .addClasspathClasses(CLASS)
- .addProgramClasses(CLASS)
- .run(CLASS)
- .assertSuccessWithOutput(EXPECTED);
- }
-
- @Test
- public void testWithDirectoryClasspath() throws Exception {
- testForD8()
- .addClasspathFiles(ToolHelper.getClassPathForTests())
- .addProgramClasses(CLASS)
- .run(CLASS)
- .assertSuccessWithOutput(EXPECTED);
- }
-}
diff --git a/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java b/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
index 1836a29..c4151d1 100644
--- a/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
@@ -463,29 +463,6 @@
}
@Test
- public void testPinnedArrayParameterTypes() throws Throwable {
- String main = "classmerging.PinnedArrayParameterTypesTest";
- Path[] programFiles =
- new Path[] {
- CF_DIR.resolve("PinnedArrayParameterTypesTest.class"),
- CF_DIR.resolve("PinnedArrayParameterTypesTest$Interface.class"),
- CF_DIR.resolve("PinnedArrayParameterTypesTest$InterfaceImpl.class"),
- CF_DIR.resolve("PinnedArrayParameterTypesTest$TestClass.class")
- };
- Set<String> preservedClassNames =
- ImmutableSet.of(
- "classmerging.PinnedArrayParameterTypesTest",
- "classmerging.PinnedArrayParameterTypesTest$Interface",
- "classmerging.PinnedArrayParameterTypesTest$InterfaceImpl",
- "classmerging.PinnedArrayParameterTypesTest$TestClass");
- runTest(
- main,
- programFiles,
- preservedClassNames::contains,
- getProguardConfig(EXAMPLE_KEEP, "-keepparameternames"));
- }
-
- @Test
public void testProguardFieldMap() throws Throwable {
String main = "classmerging.ProguardFieldMapTest";
Path[] programFiles =