Disallow class merging when instance field merging may lead to IAE
Bug: b/347676160
Change-Id: I521dc342150e8374992dd453379915e8a5e36db8
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 530ec46..ef0e11e 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -3356,6 +3356,18 @@
getKeepInfo().keepField(field);
}
+ if (mode.isFinalTreeShaking() && options.isOptimizing() && !field.getAccessFlags().isStatic()) {
+ DexType fieldBaseType = field.getType().toBaseType(appView.dexItemFactory());
+ if (fieldBaseType.isClassType()) {
+ DexClass clazz = definitionFor(fieldBaseType, context);
+ if (clazz != null
+ && AccessControl.isClassAccessible(clazz, context, appView).isPossiblyFalse()) {
+ applyMinimumKeepInfoWhenLive(
+ field.getHolder(), KeepClassInfo.newEmptyJoiner().disallowHorizontalClassMerging());
+ }
+ }
+ }
+
// Notify analyses.
analyses.forEach(analysis -> analysis.processNewlyLiveField(field, context, worklist));
}
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/InaccessibleFieldTypeMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/InaccessibleFieldTypeMergingTest.java
index b92aaff..185ac46 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/InaccessibleFieldTypeMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/InaccessibleFieldTypeMergingTest.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.classmerging.horizontal.testclasses.InaccessibleFieldTypeMergingTestClasses.BarGreeterContainer;
import com.android.tools.r8.classmerging.horizontal.testclasses.InaccessibleFieldTypeMergingTestClasses.FooGreeterContainer;
import com.android.tools.r8.classmerging.horizontal.testclasses.InaccessibleFieldTypeMergingTestClasses.Greeter;
+import com.android.tools.r8.utils.codeinspector.HorizontallyMergedClassesInspector;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -34,11 +35,7 @@
.addInnerClasses(getClass(), InaccessibleFieldTypeMergingTestClasses.class)
.addKeepMainRule(Main.class)
.addHorizontallyMergedClassesInspector(
- inspector ->
- inspector
- .assertIsCompleteMergeGroup(
- FooGreeterContainer.class, BarGreeterContainer.class)
- .assertNoOtherClassesMerged())
+ HorizontallyMergedClassesInspector::assertNoClassesMerged)
.enableInliningAnnotations()
.enableNoAccessModificationAnnotationsForClasses()
.enableNoHorizontalClassMergingAnnotations()
@@ -47,8 +44,7 @@
.setMinApi(parameters)
.compile()
.run(parameters.getRuntime(), Main.class)
- // TODO(b/347676160): Should succeed.
- .assertFailureWithErrorThatThrows(IllegalAccessError.class);
+ .assertSuccessWithOutputLines("Foo!", "Bar!");
}
static class Main {