Version 1.0.28.
Merge: Convert invokevirtual to invoke-direct when target is private method on current class.
CL: https://r8-review.googlesource.com/c/r8/+/21390
Merge: Only rewrite invoke-virtual to invoke-direct if the direct resolution result is on the target of the invoke and *not* a base class.
CL: https://r8-review.googlesource.com/c/r8/+/21393
Merge: Actually make sure that we only rewrite invoke-virtual if targeting a method in the current class.
CL: https://r8-review.googlesource.com/c/r8/+/21394
R=sgjesse@google.com, zerny@google.com
Bug: 80124071
Change-Id: Ib4827771819026318a8a68af5620bb98aed25303
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 76ce369..6a39500 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "v1.0.27";
+ public static final String LABEL = "v1.0.28";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/graph/CfCode.java b/src/main/java/com/android/tools/r8/graph/CfCode.java
index a9b3c9e..ba00174 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -149,7 +149,7 @@
}
@Override
- public IRCode buildIR(DexEncodedMethod encodedMethod, InternalOptions options)
+ public IRCode buildIR(DexEncodedMethod encodedMethod, AppInfo info, InternalOptions options)
throws ApiLevelException {
throw new Unimplemented("Converting Java class- file bytecode to IR not yet supported");
}
diff --git a/src/main/java/com/android/tools/r8/graph/Code.java b/src/main/java/com/android/tools/r8/graph/Code.java
index b6c1583..52c4f27 100644
--- a/src/main/java/com/android/tools/r8/graph/Code.java
+++ b/src/main/java/com/android/tools/r8/graph/Code.java
@@ -17,11 +17,15 @@
public abstract class Code extends CachedHashValueDexItem {
- public abstract IRCode buildIR(DexEncodedMethod encodedMethod, InternalOptions options)
+ public abstract IRCode buildIR(
+ DexEncodedMethod encodedMethod,
+ AppInfo appInfo,
+ InternalOptions options)
throws ApiLevelException;
public IRCode buildInliningIR(
DexEncodedMethod encodedMethod,
+ AppInfo appInfo,
InternalOptions options,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition)
diff --git a/src/main/java/com/android/tools/r8/graph/DexCode.java b/src/main/java/com/android/tools/r8/graph/DexCode.java
index 1517dfb..14e7091 100644
--- a/src/main/java/com/android/tools/r8/graph/DexCode.java
+++ b/src/main/java/com/android/tools/r8/graph/DexCode.java
@@ -163,19 +163,20 @@
}
@Override
- public IRCode buildIR(DexEncodedMethod encodedMethod, InternalOptions options)
+ public IRCode buildIR(DexEncodedMethod encodedMethod, AppInfo appInfo,
+ InternalOptions options)
throws ApiLevelException {
DexSourceCode source =
new DexSourceCode(
this, encodedMethod, null, options.lineNumberOptimization == LineNumberOptimization.ON);
- IRBuilder builder = new IRBuilder(encodedMethod, source, options);
+ IRBuilder builder = new IRBuilder(encodedMethod, appInfo, source, options);
return builder.build();
}
@Override
public IRCode buildInliningIR(
DexEncodedMethod encodedMethod,
- InternalOptions options,
+ AppInfo appInfo, InternalOptions options,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition)
throws ApiLevelException {
@@ -185,7 +186,8 @@
encodedMethod,
callerPosition,
options.lineNumberOptimization == LineNumberOptimization.ON);
- IRBuilder builder = new IRBuilder(encodedMethod, source, options, valueNumberGenerator);
+ IRBuilder builder =
+ new IRBuilder(encodedMethod, appInfo, source, options, valueNumberGenerator);
return builder.build();
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 6a7726f..fafd904 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -217,20 +217,24 @@
compilationState = CompilationState.NOT_PROCESSED;
}
- public IRCode buildIR(InternalOptions options) throws ApiLevelException {
- return code == null ? null : code.buildIR(this, options);
+ public IRCode buildIR(AppInfo appInfo, InternalOptions options) throws ApiLevelException {
+ return code == null ? null : code.buildIR(this, appInfo, options);
}
public IRCode buildInliningIRForTesting(
InternalOptions options, ValueNumberGenerator valueNumberGenerator)
throws ApiLevelException {
- return buildInliningIR(options, valueNumberGenerator, null);
+ return buildInliningIR(null, options, valueNumberGenerator, null);
}
public IRCode buildInliningIR(
- InternalOptions options, ValueNumberGenerator valueNumberGenerator, Position callerPosition)
+ AppInfo appInfo,
+ InternalOptions options,
+ ValueNumberGenerator valueNumberGenerator,
+ Position callerPosition)
throws ApiLevelException {
- return code.buildInliningIR(this, options, valueNumberGenerator, callerPosition);
+ return code.buildInliningIR(
+ this, appInfo, options, valueNumberGenerator, callerPosition);
}
public void setCode(Code code) {
diff --git a/src/main/java/com/android/tools/r8/graph/JarCode.java b/src/main/java/com/android/tools/r8/graph/JarCode.java
index 11a70a3..8a37d84 100644
--- a/src/main/java/com/android/tools/r8/graph/JarCode.java
+++ b/src/main/java/com/android/tools/r8/graph/JarCode.java
@@ -94,46 +94,46 @@
}
@Override
- public IRCode buildIR(DexEncodedMethod encodedMethod, InternalOptions options)
+ public IRCode buildIR(DexEncodedMethod encodedMethod, AppInfo appInfo, InternalOptions options)
throws ApiLevelException {
triggerDelayedParsingIfNeccessary();
return options.debug
- ? internalBuildWithLocals(encodedMethod, options, null, null)
- : internalBuild(encodedMethod, options, null, null);
+ ? internalBuildWithLocals(encodedMethod, appInfo, options, null, null)
+ : internalBuild(encodedMethod, appInfo, options, null, null);
}
@Override
public IRCode buildInliningIR(
DexEncodedMethod encodedMethod,
- InternalOptions options,
+ AppInfo appInfo, InternalOptions options,
ValueNumberGenerator generator,
Position callerPosition)
throws ApiLevelException {
assert generator != null;
triggerDelayedParsingIfNeccessary();
return options.debug
- ? internalBuildWithLocals(encodedMethod, options, generator, callerPosition)
- : internalBuild(encodedMethod, options, generator, callerPosition);
+ ? internalBuildWithLocals(encodedMethod, appInfo, options, generator, callerPosition)
+ : internalBuild(encodedMethod, appInfo, options, generator, callerPosition);
}
private IRCode internalBuildWithLocals(
DexEncodedMethod encodedMethod,
- InternalOptions options,
+ AppInfo appInfo, InternalOptions options,
ValueNumberGenerator generator,
Position callerPosition)
throws ApiLevelException {
try {
- return internalBuild(encodedMethod, options, generator, callerPosition);
+ return internalBuild(encodedMethod, appInfo, options, generator, callerPosition);
} catch (InvalidDebugInfoException e) {
options.warningInvalidDebugInfo(encodedMethod, origin, e);
node.localVariables.clear();
- return internalBuild(encodedMethod, options, generator, callerPosition);
+ return internalBuild(encodedMethod, appInfo, options, generator, callerPosition);
}
}
private IRCode internalBuild(
DexEncodedMethod encodedMethod,
- InternalOptions options,
+ AppInfo appInfo, InternalOptions options,
ValueNumberGenerator generator,
Position callerPosition)
throws ApiLevelException {
@@ -144,8 +144,8 @@
method.getHolder(), node, application, encodedMethod.method, callerPosition);
IRBuilder builder =
(generator == null)
- ? new IRBuilder(encodedMethod, source, options)
- : new IRBuilder(encodedMethod, source, options, generator);
+ ? new IRBuilder(encodedMethod, appInfo, source, options)
+ : new IRBuilder(encodedMethod, appInfo, source, options, generator);
return builder.build();
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 84b4666..2af5f03 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.InternalCompilerError;
import com.android.tools.r8.errors.InvalidDebugInfoException;
+import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -260,18 +261,15 @@
private final LinkedList<BasicBlock> blocks = new LinkedList<>();
private BasicBlock currentBlock = null;
-
private final List<BasicBlock.Pair> needGotoToCatchBlocks = new ArrayList<>();
-
final private ValueNumberGenerator valueNumberGenerator;
-
private final DexEncodedMethod method;
+ private final AppInfo appInfo;
// Source code to build IR from. Null if already built.
private SourceCode source;
- boolean throwingInstructionInCurrentBlock = false;
-
+ private boolean throwingInstructionInCurrentBlock = false;
private final InternalOptions options;
// Pending local reads.
@@ -280,16 +278,17 @@
private int nextBlockNumber = 0;
- public IRBuilder(DexEncodedMethod method, SourceCode source, InternalOptions options) {
- this(method, source, options, new ValueNumberGenerator());
+ public IRBuilder(DexEncodedMethod method, AppInfo appInfo,
+ SourceCode source, InternalOptions options) {
+ this(method, appInfo, source, options, new ValueNumberGenerator());
}
public IRBuilder(
- DexEncodedMethod method,
- SourceCode source,
+ DexEncodedMethod method, AppInfo appInfo, SourceCode source,
InternalOptions options, ValueNumberGenerator valueNumberGenerator) {
assert source != null;
this.method = method;
+ this.appInfo = appInfo;
this.source = source;
this.valueNumberGenerator = valueNumberGenerator;
this.options = options;
@@ -1007,7 +1006,7 @@
public void addInvoke(Type type, DexItem item, DexProto callSiteProto, List<Value> arguments)
throws ApiLevelException {
- if (type == Invoke.Type.POLYMORPHIC) {
+ if (type == Type.POLYMORPHIC) {
assert item instanceof DexMethod;
if (!options.canUseInvokePolymorphic()) {
throw new ApiLevelException(
@@ -1022,6 +1021,19 @@
null /* sourceString */);
}
}
+ if (appInfo != null && type == Type.VIRTUAL) {
+ // If an invoke-virtual targets a private method in the current class overriding will
+ // not apply (see jvm spec on method resolution 5.4.3.3 and overriding 5.4.5) and
+ // therefore we use an invoke-direct instead. We need to do this as the Android Runtime
+ // will not allow invoke-virtual of a private method.
+ DexMethod invocationMethod = (DexMethod) item;
+ if (invocationMethod.holder == method.method.holder) {
+ DexEncodedMethod directTarget = appInfo.lookupDirectTarget(invocationMethod);
+ if (directTarget != null && invocationMethod.holder == directTarget.method.holder) {
+ type = Type.DIRECT;
+ }
+ }
+ }
add(Invoke.create(type, item, callSiteProto, null, arguments));
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index ed3ad4d..63f4efc 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -520,7 +520,7 @@
Log.debug(getClass(), "Original code for %s:\n%s",
method.toSourceString(), logCode(options, method));
}
- IRCode code = method.buildIR(options);
+ IRCode code = method.buildIR(appInfo, options);
if (code == null) {
feedback.markProcessed(method, Constraint.NEVER);
return;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java
index 31fc38f..1d17278 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java
@@ -56,7 +56,7 @@
return;
}
DexEncodedMethod initializer = clazz.getClassInitializer();
- IRCode code = initializer.getCode().buildIR(initializer, options);
+ IRCode code = initializer.getCode().buildIR(initializer, appInfo, options);
Reference2IntMap<DexField> ordinalsMap = new Reference2IntArrayMap<>();
ordinalsMap.defaultReturnValue(-1);
InstructionIterator it = code.instructionIterator();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index a7f8520..82ca15f 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -239,10 +239,10 @@
Position callerPosition)
throws ApiLevelException {
if (target.isProcessed()) {
- return target.buildInliningIR(options, generator, callerPosition);
+ return target.buildInliningIR(appInfo, options, generator, callerPosition);
} else {
// Build the IR for a yet not processed method, and perform minimal IR processing.
- IRCode code = target.buildInliningIR(options, generator, callerPosition);
+ IRCode code = target.buildInliningIR(appInfo, options, generator, callerPosition);
new LensCodeRewriter(graphLense, appInfo).rewrite(code, target);
return code;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index 536e4b7..378642b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.ApiLevelException;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DebugLocalInfo;
@@ -997,10 +998,11 @@
}
@Override
- public IRCode buildIR(DexEncodedMethod encodedMethod, InternalOptions options)
+ public IRCode buildIR(DexEncodedMethod encodedMethod,
+ AppInfo appInfo, InternalOptions options)
throws ApiLevelException {
OutlineSourceCode source = new OutlineSourceCode(outline);
- IRBuilder builder = new IRBuilder(encodedMethod, source, options);
+ IRBuilder builder = new IRBuilder(encodedMethod, appInfo, source, options);
return builder.build();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java
index 25b1d1b..8f27e11 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java
@@ -93,7 +93,7 @@
List<DexEncodedField> switchMapFields = Arrays.stream(clazz.staticFields())
.filter(this::maybeIsSwitchMap).collect(Collectors.toList());
if (!switchMapFields.isEmpty()) {
- IRCode initializer = clazz.getClassInitializer().buildIR(options);
+ IRCode initializer = clazz.getClassInitializer().buildIR(appInfo, options);
switchMapFields.forEach(field -> extractSwitchMap(field, initializer));
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/SynthesizedCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/SynthesizedCode.java
index 26ef333..19b8e6a 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/SynthesizedCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/SynthesizedCode.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.ApiLevelException;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexType;
@@ -33,9 +34,10 @@
}
@Override
- public final IRCode buildIR(DexEncodedMethod encodedMethod, InternalOptions options)
+ public final IRCode buildIR(
+ DexEncodedMethod encodedMethod, AppInfo appInfo, InternalOptions options)
throws ApiLevelException {
- return new IRBuilder(encodedMethod, sourceCode, options).build();
+ return new IRBuilder(encodedMethod, appInfo, sourceCode, options).build();
}
@Override
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 90bd458..71ffe54 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -1211,7 +1211,7 @@
private void handleProguardReflectiveBehavior(DexEncodedMethod method) {
try {
- IRCode code = method.buildIR(options);
+ IRCode code = method.buildIR(appInfo, options);
code.instructionIterator().forEachRemaining(this::handleProguardReflectiveBehavior);
} catch (ApiLevelException e) {
// Ignore this exception here. It will be hit again further in the pipeline when
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
index 248546d..72382ce 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
@@ -49,7 +49,7 @@
AppInfoWithSubtyping appInfo = new AppInfoWithSubtyping(dexApplication);
DexInspector dexInspector = new DexInspector(appInfo.app);
DexEncodedMethod foo = dexInspector.clazz(CLASS_NAME).method(signature).getMethod();
- IRCode irCode = foo.buildIR(TEST_OPTIONS);
+ IRCode irCode = foo.buildIR(appInfo, TEST_OPTIONS);
TypeAnalysis analysis = new TypeAnalysis(appInfo, foo, irCode);
analysis.run();
inspector.accept(appInfo, analysis);
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
index 9715a67..e93400f 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
@@ -124,7 +124,7 @@
new MethodSignature("subtractConstants8bitRegisters", "int", ImmutableList.of()))
.getMethod();
try {
- IRCode irCode = subtract.buildIR(TEST_OPTIONS);
+ IRCode irCode = subtract.buildIR(appInfo, TEST_OPTIONS);
TypeAnalysis analysis = new TypeAnalysis(appInfo, subtract, irCode);
analysis.run();
analysis.forEach((v, l) -> {
@@ -143,7 +143,7 @@
.method(new MethodSignature("fibonacci", "int", ImmutableList.of("int")))
.getMethod();
try {
- IRCode irCode = fib.buildIR(TEST_OPTIONS);
+ IRCode irCode = fib.buildIR(appInfo, TEST_OPTIONS);
TypeAnalysis analysis = new TypeAnalysis(appInfo, fib, irCode);
analysis.run();
analysis.forEach((v, l) -> {
@@ -162,7 +162,7 @@
.method(new MethodSignature("test1", "int[]", ImmutableList.of()))
.getMethod();
try {
- IRCode irCode = test1.buildIR(TEST_OPTIONS);
+ IRCode irCode = test1.buildIR(appInfo, TEST_OPTIONS);
TypeAnalysis analysis = new TypeAnalysis(appInfo, test1, irCode);
analysis.run();
Value array = null;
@@ -198,7 +198,7 @@
.method(new MethodSignature("test4", "int[]", ImmutableList.of()))
.getMethod();
try {
- IRCode irCode = test4.buildIR(TEST_OPTIONS);
+ IRCode irCode = test4.buildIR(appInfo, TEST_OPTIONS);
TypeAnalysis analysis = new TypeAnalysis(appInfo, test4, irCode);
analysis.run();
Value array = null;
@@ -234,7 +234,7 @@
.method(new MethodSignature("loop2", "void", ImmutableList.of()))
.getMethod();
try {
- IRCode irCode = loop2.buildIR(TEST_OPTIONS);
+ IRCode irCode = loop2.buildIR(appInfo, TEST_OPTIONS);
TypeAnalysis analysis = new TypeAnalysis(appInfo, loop2, irCode);
analysis.run();
analysis.forEach((v, l) -> {
@@ -258,7 +258,7 @@
.method(new MethodSignature("test2_throw", "int", ImmutableList.of()))
.getMethod();
try {
- IRCode irCode = test2.buildIR(TEST_OPTIONS);
+ IRCode irCode = test2.buildIR(appInfo, TEST_OPTIONS);
TypeAnalysis analysis = new TypeAnalysis(appInfo, test2, irCode);
analysis.run();
analysis.forEach((v, l) -> {
@@ -290,7 +290,7 @@
CheckCast.class, new ClassTypeLatticeElement(test, true),
NewInstance.class, new ClassTypeLatticeElement(test, false));
try {
- IRCode irCode = method.buildIR(TEST_OPTIONS);
+ IRCode irCode = method.buildIR(appInfo, TEST_OPTIONS);
TypeAnalysis analysis = new TypeAnalysis(appInfo, method, irCode);
analysis.run();
analysis.forEach((v, l) -> verifyTypeEnvironment(expectedLattices, v, l));
@@ -314,7 +314,7 @@
InstanceOf.class, PRIMITIVE,
StaticGet.class, new ClassTypeLatticeElement(test, true));
try {
- IRCode irCode = method.buildIR(TEST_OPTIONS);
+ IRCode irCode = method.buildIR(appInfo, TEST_OPTIONS);
TypeAnalysis analysis = new TypeAnalysis(appInfo, method, irCode);
analysis.run();
analysis.forEach((v, l) -> verifyTypeEnvironment(expectedLattices, v, l));
diff --git a/src/test/java/com/android/tools/r8/jasmin/Regress80124071.java b/src/test/java/com/android/tools/r8/jasmin/Regress80124071.java
new file mode 100644
index 0000000..0eda515
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/jasmin/Regress80124071.java
@@ -0,0 +1,71 @@
+// Copyright (c) 2018, 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.jasmin;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.jasmin.JasminBuilder.ClassFileVersion;
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+
+public class Regress80124071 extends JasminTestBase {
+
+ private JasminBuilder buildClass() {
+ JasminBuilder builder = new JasminBuilder(ClassFileVersion.JDK_1_4);
+ JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
+
+ clazz.addPrivateVirtualMethod("privateMethod", ImmutableList.of(), "V",
+ ".limit stack 2",
+ ".limit locals 1",
+ "getstatic java/lang/System/out Ljava/io/PrintStream;",
+ "ldc \"privateMethod\"",
+ "invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V",
+ "return");
+
+ clazz.addDefaultConstructor();
+
+ clazz.addMainMethod(
+ ".limit stack 3",
+ ".limit locals 1",
+ "new Test",
+ "dup",
+ "invokespecial Test/<init>()V",
+ // Should have been invokespecial but JVM is OK with it so we need to transform
+ // to invoke-direct to be able to run on Art.
+ "invokevirtual Test/privateMethod()V",
+ "new TestSub",
+ "dup",
+ "dup",
+ "invokespecial TestSub/<init>()V",
+ // Should have been invokespecial but JVM is OK with it and invokes the private method
+ // on the Test class. Therefore, there is no virtual dispatch and we need to transform
+ // to invoke-direct to be able to run on Art.
+ "invokevirtual Test/privateMethod()V",
+ "invokevirtual TestSub/privateMethod()V",
+ "return");
+
+ JasminBuilder.ClassBuilder subclazz = builder.addClass("TestSub", "Test");
+
+ subclazz.addVirtualMethod("privateMethod", ImmutableList.of(), "V",
+ ".limit stack 2",
+ ".limit locals 1",
+ "getstatic java/lang/System/out Ljava/io/PrintStream;",
+ "ldc \"privateMethod2\"",
+ "invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V",
+ "return");
+
+ return builder;
+ }
+
+ @Test
+ public void test() throws Exception {
+ JasminBuilder builder = buildClass();
+ String jvm = runOnArtDx(builder, "Test");
+ String dx = runOnJava(builder, "Test");
+ assertEquals(jvm, dx);
+ String d8 = runOnArtD8(builder, "Test");
+ assertEquals(jvm, d8);
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index 5df6bd5..5a04d3e 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -25,6 +25,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DebugLocalInfo;
@@ -619,7 +620,7 @@
DexAnnotationSet.empty(),
DexAnnotationSetRefList.empty(),
code);
- IRCode ir = code.buildIR(method, options);
+ IRCode ir = code.buildIR(method, null, options);
RegisterAllocator allocator = new LinearScanRegisterAllocator(ir, options);
method.setCode(ir, allocator, options);
directMethods[i] = method;
diff --git a/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java b/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
index d2391ff..503e1d5 100644
--- a/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
+++ b/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
@@ -67,7 +67,7 @@
DexEncodedMethod method = getMethod(originalApplication, methodSig);
// Get the IR pre-optimization.
- IRCode code = method.buildIR(new InternalOptions());
+ IRCode code = method.buildIR(null, new InternalOptions());
// Find the exit block and assert that the value is a phi merging the exceptional edge
// with the normal edge.