diff --git a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/B138912149.java b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/B138912149.java new file mode 100644 index 000000000..280853e39 --- /dev/null +++ b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/B138912149.java @@ -0,0 +1,82 @@ +// 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.ir.optimize.membervaluepropagation; + +import static org.junit.Assume.assumeTrue; + +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 B138912149 extends TestBase { + + private final TestParameters parameters; + + @Parameters(name = "{0}") + public static TestParametersCollection data() { + return getTestParameters().withAllRuntimes().build(); + } + + public B138912149(TestParameters parameters) { + this.parameters = parameters; + } + + @Test + public void test() throws Exception { + testForR8(parameters.getBackend()) + .addInnerClasses(B138912149.class) + .addKeepMainRule(TestClass.class) + .setMinApi(parameters.getRuntime()) + .compile() + .run(parameters.getRuntime(), TestClass.class) + // TODO(b/138912149): Should be "The end". + .assertSuccessWithOutputLines("Dead code 2", "The end"); + } + + @Test + public void testJvm() throws Exception { + assumeTrue(parameters.isCfRuntime()); + testForJvm() + .addTestClasspath() + .run(parameters.getRuntime(), TestClass.class) + .assertSuccessWithOutputLines("The end"); + } + + static class TestClass { + + public static void main(String... args) { + if (A.alwaysFalse) { + System.out.println("Dead code 1"); + } + if (B.alwaysFalse || !B.alwaysTrue) { + System.out.println("Dead code 2"); + } + System.out.println("The end"); + } + } + + static class A { + static boolean alwaysFalse; + + static { + alwaysFalse = false; + } + } + + static class B extends A { + static boolean alwaysTrue; + + static { + alwaysTrue = alwaysFalse; + // Either keep this static-put or remove both static-put's and put `true` to `alwaysTrue`. + alwaysTrue = true; + } + } +} diff --git a/src/test/java/com/android/tools/r8/shaking/EffectivelyFinalStaticFieldsTest.java b/src/test/java/com/android/tools/r8/shaking/EffectivelyFinalStaticFieldsTest.java index 0cc9afdc3..1b54e8ad7 100644 --- a/src/test/java/com/android/tools/r8/shaking/EffectivelyFinalStaticFieldsTest.java +++ b/src/test/java/com/android/tools/r8/shaking/EffectivelyFinalStaticFieldsTest.java @@ -66,10 +66,11 @@ public void testR8() throws Exception { assertTrue( mainMethod.streamInstructions().noneMatch( i -> i.isConstString("Dead code: 1", JumboStringMode.ALLOW))); - assertTrue( + // TODO(b/138913138): effectively final, and default value is set. + assertFalse( mainMethod.streamInstructions().noneMatch( i -> i.isConstString("Dead code: 2", JumboStringMode.ALLOW))); - // TODO(b/138913138): not trivial; assigned only once in + // TODO(b/138913138): not trivial; assigned multiple times, but can determine the value. assertFalse( mainMethod.streamInstructions().noneMatch( i -> i.isConstString("Dead code: 3", JumboStringMode.ALLOW))); @@ -92,9 +93,7 @@ public void testR8() throws Exception { i -> i.isConstString("Dead code: 8", JumboStringMode.ALLOW))); }) .run(parameters.getRuntime(), MAIN) - .assertSuccess(); - // TODO(b/138912149): should not be shrunk. - //.assertSuccessWithOutputLines("The end"); + .assertSuccessWithOutputLines("The end"); } static class TestClass { @@ -102,9 +101,11 @@ public static void main(String... args) { if (StaticFieldWithoutInitialization_Z.alwaysFalse) { System.out.println("Dead code: 1"); } + StaticFieldWithInitialization_Z.not_clinit(); if (StaticFieldWithInitialization_Z.alwaysFalse) { System.out.println("Dead code: 2"); } + StaticFieldWithNonTrivialInitialization_Z.not_clinit(); if (StaticFieldWithNonTrivialInitialization_Z.alwaysFalse || !StaticFieldWithNonTrivialInitialization_Z.alwaysTrue) { System.out.println("Dead code: 3"); @@ -140,7 +141,8 @@ static class StaticFieldWithoutInitialization_Z { @NeverMerge static class StaticFieldWithInitialization_Z { static boolean alwaysFalse; - static { + @NeverInline + static void not_clinit() { alwaysFalse = false; } } @@ -149,9 +151,9 @@ static class StaticFieldWithInitialization_Z { static class StaticFieldWithNonTrivialInitialization_Z extends StaticFieldWithInitialization_Z { static boolean alwaysTrue; - static { + @NeverInline + static void not_clinit() { alwaysTrue = alwaysFalse; - // TODO(b/138912149): should not be shrunk. alwaysTrue = true; } }