blob: 9e0429b3aaaf5a26289ccd55e9a7c8da5290ef44 [file] [log] [blame]
// 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.shaking;
import static com.android.tools.r8.utils.DexInspectorMatchers.isPresent;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.VmTestRunner;
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
import com.android.tools.r8.naming.MemberNaming.FieldSignature;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DexInspector;
import com.android.tools.r8.utils.DexInspector.ClassSubject;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(VmTestRunner.class)
public class FieldTypeTest extends TestBase {
@Ignore("b/78788577")
@Test
public void test_brokenTypeHierarchy() throws Exception {
JasminBuilder jasminBuilder = new JasminBuilder();
// interface Itf
ClassBuilder itf = jasminBuilder.addInterface("Itf");
MethodSignature foo = itf.addAbstractMethod("foo", ImmutableList.of(), "V");
// class Impl /* implements Itf */
ClassBuilder impl = jasminBuilder.addClass("Impl");
impl.addDefaultConstructor();
impl.addVirtualMethod("foo", ImmutableList.of(), "V",
".limit locals 2",
".limit stack 2",
"getstatic java/lang/System/out Ljava/io/PrintStream;",
"ldc \"" + "foo" + "\"",
"invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
"return");
impl.addVirtualMethod("toString", ImmutableList.of(), "Ljava/lang/String;",
".limit locals 1",
".limit stack 2",
"ldc \"" + impl.name + "\"",
"areturn");
ClassBuilder client = jasminBuilder.addClass("Client");
FieldSignature obj = client.addStaticFinalField("obj", itf.getDescriptor(), null);
client.addClassInitializer(
".limit locals 1",
".limit stack 2",
"new " + impl.name,
"dup",
"invokespecial " + impl.name + "/<init>()V",
"putstatic " + client.name + "/" + obj.name + " " + itf.getDescriptor(),
"return"
);
ClassBuilder mainClass = jasminBuilder.addClass("Main");
mainClass.addMainMethod(
".limit locals 2",
".limit stack 2",
"getstatic java/lang/System/out Ljava/io/PrintStream;",
"getstatic " + client.name + "/" + obj.name + " " + itf.getDescriptor(),
/*
"astore_0",
"aload_0",
// java.lang.IncompatibleClassChangeError:
// Class Impl does not implement the requested interface Itf
"invokeinterface " + itf.name + "/" + foo.name + "()V 1",
"aload_0",
*/
"invokevirtual java/io/PrintStream/print(Ljava/lang/Object;)V",
"return"
);
final String mainClassName = mainClass.name;
String proguardConfig = keepMainProguardConfiguration(mainClass.name, false, false);
// Run input program on java.
Path outputDirectory = temp.newFolder().toPath();
jasminBuilder.writeClassFiles(outputDirectory);
ProcessResult javaResult = ToolHelper.runJava(outputDirectory, mainClassName);
assertEquals(0, javaResult.exitCode);
assertThat(javaResult.stdout, containsString(impl.name));
AndroidApp processedApp = compileWithR8(jasminBuilder.build(), proguardConfig,
// Disable inlining to avoid the (short) tested method from being inlined and then removed.
internalOptions -> internalOptions.enableInlining = false);
// Run processed (output) program on ART
ProcessResult artResult = runOnArtRaw(processedApp, mainClassName);
assertEquals(0, artResult.exitCode);
assertThat(artResult.stdout, containsString(impl.name));
assertEquals(-1, artResult.stderr.indexOf("DoFieldPut"));
DexInspector inspector = new DexInspector(processedApp);
ClassSubject itfSubject = inspector.clazz(itf.name);
assertThat(itfSubject, isPresent());
}
}