blob: a958c3a1068889e1cafae6d231662f4599dbbbac [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.cf;
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.cf.code.CfLabel;
import com.android.tools.r8.cf.code.CfTryCatch;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexCode.Try;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.Sets;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.Set;
import org.junit.Test;
public class IdenticalCatchHandlerTest extends TestBase {
private static class TestClass {
public void foo(Object a, Object b, Object c) {
if (a == null) {
try {
System.out.println(b.toString());
} catch (RuntimeException e) {
}
} else {
try {
System.out.println(c.toString());
} catch (RuntimeException e) {
}
}
System.out.println("Hello");
}
}
@Test
public void test() throws Exception {
byte[] inputBytes = ToolHelper.getClassAsBytes(TestClass.class);
AndroidApp inputApp =
AndroidApp.builder()
.addClassProgramData(inputBytes, Origin.unknown())
.addLibraryFiles(ToolHelper.getJava8RuntimeJar())
.build();
assertEquals(2, countCatchHandlers(inputApp));
AndroidApp outputDexApp =
ToolHelper.runR8(
ToolHelper.prepareR8CommandBuilder(inputApp)
.setDisableTreeShaking(true)
.setDisableMinification(true)
.build());
assertEquals(1, countCatchHandlers(outputDexApp));
AndroidApp outputCfApp =
ToolHelper.runR8(
ToolHelper.prepareR8CommandBuilder(inputApp, ClassFileConsumer.emptyConsumer())
.setDisableTreeShaking(true)
.setDisableMinification(true)
.build());
assertEquals(1, countCatchHandlers(outputCfApp));
}
private int countCatchHandlers(AndroidApp inputApp) throws Exception {
CodeInspector inspector = new CodeInspector(inputApp);
DexClass dexClass = inspector.clazz(TestClass.class).getDexClass();
Code code = dexClass.virtualMethods().get(0).getCode();
if (code.isCfCode()) {
CfCode cfCode = code.asCfCode();
Set<CfLabel> targets = Sets.newIdentityHashSet();
for (CfTryCatch tryCatch : cfCode.getTryCatchRanges()) {
targets.addAll(tryCatch.targets);
}
return targets.size();
} else if (code.isDexCode()) {
DexCode dexCode = code.asDexCode();
IntSet targets = new IntOpenHashSet();
for (Try aTry : dexCode.tries) {
targets.add(aTry.handlerOffset);
}
return targets.size();
} else {
throw new Unimplemented(code.getClass().getName());
}
}
}