Fix verification error from missing catch all handler Bug: 174167294 Change-Id: I9d8dbe837986d396adc9527a2edbf856692e9477
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java index 51c1c01..3e1f768 100644 --- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java +++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -312,7 +312,11 @@ // Insert the definition of the replacement. replacement.setPosition(position); if (block.hasCatchHandlers()) { - iterator.split(code, blocks).listIterator(code).add(replacement); + BasicBlock splitBlock = iterator.split(code, blocks); + splitBlock.listIterator(code).add(replacement); + assert block.hasCatchHandlers(); + assert !splitBlock.hasCatchHandlers(); + splitBlock.copyCatchHandlers(code, blocks, block, appView.options()); } else { iterator.add(replacement); } @@ -412,7 +416,11 @@ // Insert the definition of the replacement. replacement.setPosition(position); if (block.hasCatchHandlers()) { - iterator.split(code, blocks).listIterator(code).add(replacement); + BasicBlock splitBlock = iterator.split(code, blocks); + splitBlock.listIterator(code).add(replacement); + assert block.hasCatchHandlers(); + assert !splitBlock.hasCatchHandlers(); + splitBlock.copyCatchHandlers(code, blocks, block, appView.options()); } else { iterator.add(replacement); }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/ValuePropagationWithCatchHandlersTest.java b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/ValuePropagationWithCatchHandlersTest.java new file mode 100644 index 0000000..32dbb5d --- /dev/null +++ b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/ValuePropagationWithCatchHandlersTest.java
@@ -0,0 +1,69 @@ +// Copyright (c) 2020, 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.membervaluepropagation; + +import com.android.tools.r8.TestBase; +import com.android.tools.r8.TestParameters; +import com.android.tools.r8.TestParametersCollection; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +@RunWith(Parameterized.class) +public class ValuePropagationWithCatchHandlersTest extends TestBase { + + private final TestParameters parameters; + + @Parameters(name = "{0}") + public static TestParametersCollection data() { + return TestBase.getTestParameters().withAllRuntimesAndApiLevels().build(); + } + + public ValuePropagationWithCatchHandlersTest(TestParameters parameters) { + this.parameters = parameters; + } + + @Test + public void test() throws Exception { + testForR8(parameters.getBackend()) + .addInnerClasses(getClass()) + .addKeepMainRule(Main.class) + .setMinApi(parameters.getApiLevel()) + .compile() + .run(parameters.getRuntime(), Main.class) + .assertSuccessWithOutputLines("Woops!"); + } + + static class Main { + + public static void main(String[] args) { + try { + test(); + } catch (ExceptionInInitializerError e) { + System.out.println("Woops!"); + } + } + + static synchronized void test() { + System.out.println(Greeter.getInstance()); + } + } + + static class Greeter { + + static final Greeter INSTANCE = new Greeter(); + + static { + if (System.currentTimeMillis() > 0) { + throw new RuntimeException(); + } + } + + public static Greeter getInstance() { + return INSTANCE; + } + } +}