Reproduce proto builder optimization bug
Change-Id: I8fbf0a3224d32e65bfd2da7010a130e4ad5cdc04
Bug: 155416893
diff --git a/src/test/examplesProto/proto2/BuilderOnlyReferencedFromDynamicMethodTestClass.java b/src/test/examplesProto/proto2/BuilderOnlyReferencedFromDynamicMethodTestClass.java
new file mode 100644
index 0000000..e3707dc
--- /dev/null
+++ b/src/test/examplesProto/proto2/BuilderOnlyReferencedFromDynamicMethodTestClass.java
@@ -0,0 +1,24 @@
+// 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 proto2;
+
+import com.android.tools.r8.proto2.TestProto.Primitives;
+import com.google.protobuf.GeneratedMessageLite;
+import com.google.protobuf.InvalidProtocolBufferException;
+
+public class BuilderOnlyReferencedFromDynamicMethodTestClass {
+
+ public static void main(String[] args) {
+ GeneratedMessageLite<?, ?> primitivesInDisguise;
+ try {
+ primitivesInDisguise = Primitives.parseFrom(new byte[0]);
+ } catch (InvalidProtocolBufferException e) {
+ System.out.println("Unexpected exception: " + e);
+ throw new RuntimeException(e);
+ }
+ Primitives primitives = (Primitives) primitivesInDisguise.toBuilder().build();
+ Printer.print(primitives);
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderOnlyReferencedFromDynamicMethodTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderOnlyReferencedFromDynamicMethodTest.java
new file mode 100644
index 0000000..2153126
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderOnlyReferencedFromDynamicMethodTest.java
@@ -0,0 +1,74 @@
+// 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.internal.proto;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class Proto2BuilderOnlyReferencedFromDynamicMethodTest extends ProtoShrinkingTestBase {
+
+ private static final String MAIN = "proto2.BuilderOnlyReferencedFromDynamicMethodTestClass";
+
+ private static List<Path> PROGRAM_FILES =
+ ImmutableList.of(PROTO2_EXAMPLES_JAR, PROTO2_PROTO_JAR, PROTOBUF_LITE_JAR);
+
+ private final TestParameters parameters;
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ public Proto2BuilderOnlyReferencedFromDynamicMethodTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void test() throws Exception {
+ testForR8(parameters.getBackend())
+ .addProgramFiles(PROGRAM_FILES)
+ .addKeepMainRule(MAIN)
+ .addKeepRuleFiles(PROTOBUF_LITE_PROGUARD_RULES)
+ .allowAccessModification()
+ .allowDiagnosticMessages()
+ .allowUnusedProguardConfigurationRules()
+ .enableProtoShrinking()
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllInfoMessagesMatch(
+ containsString("Proguard configuration rule does not match anything"))
+ .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+ .inspect(this::inspect)
+ .run(parameters.getRuntime(), MAIN)
+ .assertFailureWithErrorThatMatches(containsString("UnsupportedOperationException"));
+ // TODO(b/155416893): Should succeed with the following output.
+ // .assertSuccessWithOutputLines(
+ // "false", "0", "false", "", "false", "0", "false", "0", "false", "");
+ }
+
+ private void inspect(CodeInspector outputInspector) {
+ verifyBuilderIsAbsent(outputInspector);
+ }
+
+ private void verifyBuilderIsAbsent(CodeInspector outputInspector) {
+ assertThat(
+ outputInspector.clazz("com.android.tools.r8.proto2.TestProto$Primitives$Builder"),
+ not(isPresent()));
+ }
+}