Merge "Fix for NonVirtualOverrideTest on old VMs"
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index b86c4bd..bbc5922 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -350,6 +350,16 @@
return null;
}
+ @Override
+ public boolean isStatic() {
+ return accessFlags.isStatic();
+ }
+
+ @Override
+ public boolean isStaticMember() {
+ return false;
+ }
+
public DexEncodedMethod getClassInitializer() {
return Arrays.stream(directMethods()).filter(DexEncodedMethod::isClassInitializer).findAny()
.orElse(null);
diff --git a/src/main/java/com/android/tools/r8/graph/DexDefinition.java b/src/main/java/com/android/tools/r8/graph/DexDefinition.java
index c2ccfe3..9127b94 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDefinition.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDefinition.java
@@ -74,4 +74,8 @@
public static Stream<DexEncodedMethod> filterDexEncodedMethod(Stream<DexDefinition> stream) {
return filter(stream, DexDefinition::isDexEncodedMethod, DexDefinition::asDexEncodedMethod);
}
+
+ public abstract boolean isStatic();
+
+ public abstract boolean isStaticMember();
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
index 115e88a..42cc0ce 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
@@ -78,6 +78,16 @@
return this;
}
+ @Override
+ public boolean isStatic() {
+ return accessFlags.isStatic();
+ }
+
+ @Override
+ public boolean isStaticMember() {
+ return isStatic();
+ }
+
public boolean hasAnnotation() {
return !annotations.isEmpty();
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 5af5739..a4986a5 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -216,11 +216,24 @@
/**
* Returns true if this method can be invoked via invoke-static.
*/
+ // TODO(jsjeon): deprecate this, and use isStatic() instead.
public boolean isStaticMethod() {
checkIfObsolete();
return accessFlags.isStatic();
}
+ @Override
+ public boolean isStatic() {
+ checkIfObsolete();
+ return accessFlags.isStatic();
+ }
+
+ @Override
+ public boolean isStaticMember() {
+ checkIfObsolete();
+ return isStatic();
+ }
+
/**
* Returns true if this method is synthetic.
*/
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index 19bf655..96cc33a 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -688,27 +688,17 @@
}
public ConstNumber createIntConstant(int value) {
- return new ConstNumber(createValue(ValueType.INT), value);
- }
-
- public ConstNumber createTrue() {
- return new ConstNumber(createValue(ValueType.INT), 1);
- }
-
- public ConstNumber createFalse() {
- return new ConstNumber(createValue(ValueType.INT), 0);
+ Value out = createValue(ValueType.INT);
+ return new ConstNumber(out, value);
}
public final int getHighestBlockNumber() {
return blocks.stream().max(Comparator.comparingInt(BasicBlock::getNumber)).get().getNumber();
}
- public Instruction createConstNull(Instruction from) {
- return new ConstNumber(createValue(from.outType()), 0);
- }
-
public ConstNumber createConstNull() {
- return new ConstNumber(createValue(ValueType.OBJECT), 0);
+ Value out = createValue(ValueType.OBJECT);
+ return new ConstNumber(out, 0);
}
public boolean doAllThrowingInstructionsHavePositions() {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 57557af..194558e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -1334,7 +1334,7 @@
if (current.isInvokeMethod()) {
InvokeMethod invoke = current.asInvokeMethod();
if (invoke.getInvokedMethod() == dexItemFactory.classMethods.desiredAssertionStatus) {
- iterator.replaceCurrentInstruction(code.createFalse());
+ iterator.replaceCurrentInstruction(code.createIntConstant(0));
}
} else if (current.isStaticPut()) {
StaticPut staticPut = current.asStaticPut();
@@ -1344,7 +1344,7 @@
} else if (current.isStaticGet()) {
StaticGet staticGet = current.asStaticGet();
if (staticGet.getField().name == dexItemFactory.assertionsDisabled) {
- iterator.replaceCurrentInstruction(code.createTrue());
+ iterator.replaceCurrentInstruction(code.createIntConstant(1));
}
}
}
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 afccf95..7a0aacb 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -272,6 +272,24 @@
}
}
+ private void enqueueHolderIfDependentNonStaticMember(
+ DexClass holder, Map<DexDefinition, ProguardKeepRule> dependentItems) {
+ // Check if any dependent members are not static, and in that case enqueue the class as well.
+ // Having a dependent rule like -keepclassmembers with non static items indicates that class
+ // instances will be present even if tracing do not find any instantiation. See b/115867670.
+ for (Entry<DexDefinition, ProguardKeepRule> entry : dependentItems.entrySet()) {
+ DexDefinition dependentItem = entry.getKey();
+ if (dependentItem.isDexClass()) {
+ continue;
+ }
+ if (!dependentItem.isStaticMember()) {
+ enqueueRootItem(holder, entry.getValue());
+ // Enough to enqueue the known holder once.
+ break;
+ }
+ }
+ }
+
//
// Things to do with registering events. This is essentially the interface for byte-code
// traversals.
@@ -633,16 +651,6 @@
// Actual actions performed.
//
- static private boolean isStaticMember(DexDefinition definition) {
- if (definition.isDexEncodedMethod()) {
- return (definition.asDexEncodedMethod()).accessFlags.isStatic();
- }
- if (definition.isDexEncodedField()) {
- return (definition.asDexEncodedField()).accessFlags.isStatic();
- }
- return false;
- }
-
private void markTypeAsLive(DexType type) {
assert type.isClassType();
if (liveTypes.add(type)) {
@@ -686,16 +694,8 @@
annotations.forEach(this::handleAnnotationOfLiveType);
}
- // Check if any dependent members are not static, and in that case enqueue the class as well.
- // Having a dependent rule like -keepclassmembers with non static items indicates that class
- // instances will be present even if tracing do not find any instantiation. See b/115867670.
Map<DexDefinition, ProguardKeepRule> dependentItems = rootSet.getDependentItems(holder);
- for (Entry<DexDefinition, ProguardKeepRule> entry : dependentItems.entrySet()) {
- if (!isStaticMember(entry.getKey())) {
- enqueueRootItem(holder, entry.getValue());
- break;
- }
- }
+ enqueueHolderIfDependentNonStaticMember(holder, dependentItems);
// Add all dependent members to the workqueue.
enqueueRootItems(dependentItems);
}
@@ -1298,6 +1298,16 @@
enqueueRootItems(consequentRootSet.noShrinking);
rootSet.noOptimization.addAll(consequentRootSet.noOptimization);
rootSet.noObfuscation.addAll(consequentRootSet.noObfuscation);
+ rootSet.addDependentItems(consequentRootSet.dependentNoShrinking);
+ // Check if any newly dependent members are not static, and in that case find the holder
+ // and enqueue it as well. This is -if version of workaround for b/115867670.
+ consequentRootSet.dependentNoShrinking.forEach((precondition, dependentItems) -> {
+ if (precondition.isDexClass()) {
+ enqueueHolderIfDependentNonStaticMember(precondition.asDexClass(), dependentItems);
+ }
+ // Add all dependent members to the workqueue.
+ enqueueRootItems(dependentItems);
+ });
if (!workList.isEmpty()) {
continue;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardIfRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardIfRule.java
index 54a3f2f..6d6d943 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardIfRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardIfRule.java
@@ -72,7 +72,7 @@
Origin.unknown(),
Position.UNKNOWN,
null,
- getClassAnnotation(),
+ getClassAnnotation() == null ? null : getClassAnnotation().materialize(),
getClassAccessFlags(),
getNegatedClassAccessFlags(),
getClassTypeNegated(),
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
index 3c1fb2d..dd2bd33 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
@@ -63,7 +63,7 @@
Origin.unknown(),
Position.UNKNOWN,
null,
- getClassAnnotation(),
+ getClassAnnotation() == null ? null : getClassAnnotation().materialize(),
getClassAccessFlags(),
getNegatedClassAccessFlags(),
getClassTypeNegated(),
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
index 43227d7..30def9e 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
@@ -27,6 +27,7 @@
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.ThreadUtils;
import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import java.io.PrintStream;
import java.util.ArrayList;
@@ -34,10 +35,12 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -148,16 +151,13 @@
DexClass clazz,
ProguardConfigurationRule rule,
ProguardIfRule ifRule) {
- if (rule.getClassType().matches(clazz) == rule.getClassTypeNegated()) {
+ if (!satisfyClassType(rule, clazz)) {
return;
}
- if (!rule.getClassAccessFlags().containsAll(clazz.accessFlags)) {
+ if (!satisfyAccessFlag(rule, clazz)) {
return;
}
- if (!rule.getNegatedClassAccessFlags().containsNone(clazz.accessFlags)) {
- return;
- }
- if (!containsAnnotation(rule.getClassAnnotation(), clazz.annotations)) {
+ if (!satisfyAnnotation(rule, clazz)) {
return;
}
// In principle it should make a difference whether the user specified in a class
@@ -202,13 +202,14 @@
if (rule.getClassNames().matches(clazz.type)) {
Collection<ProguardMemberRule> memberKeepRules = rule.getMemberRules();
+ Map<Predicate<DexDefinition>, DexDefinition> preconditionSupplier;
if (rule instanceof ProguardKeepRule) {
switch (((ProguardKeepRule) rule).getType()) {
case KEEP_CLASS_MEMBERS: {
- // If we're handling -if consequent part, that means precondition already met.
- DexClass precondition = ifRule != null ? null : clazz;
- markMatchingVisibleMethods(clazz, memberKeepRules, rule, precondition);
- markMatchingFields(clazz, memberKeepRules, rule, precondition);
+ // Members mentioned at -keepclassmembers always depend on their holder.
+ preconditionSupplier = ImmutableMap.of((definition -> true), clazz);
+ markMatchingVisibleMethods(clazz, memberKeepRules, rule, preconditionSupplier);
+ markMatchingFields(clazz, memberKeepRules, rule, preconditionSupplier);
break;
}
case KEEP_CLASSES_WITH_MEMBERS: {
@@ -219,20 +220,33 @@
}
case KEEP: {
markClass(clazz, rule);
- markMatchingVisibleMethods(clazz, memberKeepRules, rule, null);
- markMatchingFields(clazz, memberKeepRules, rule, null);
+ preconditionSupplier = new HashMap<>();
+ if (ifRule != null) {
+ // Static members in -keep are pinned no matter what.
+ preconditionSupplier.put(DexDefinition::isStaticMember, null);
+ // Instance members may need to be kept even though the holder is not instantiated.
+ preconditionSupplier.put(definition -> !definition.isStaticMember(), clazz);
+ } else {
+ // Members mentioned at -keep should always be pinned as long as that -keep rule is
+ // not triggered conditionally.
+ preconditionSupplier.put((definition -> true), null);
+ }
+ markMatchingVisibleMethods(clazz, memberKeepRules, rule, preconditionSupplier);
+ markMatchingFields(clazz, memberKeepRules, rule, preconditionSupplier);
break;
}
case CONDITIONAL:
- assert rule instanceof ProguardIfRule;
throw new Unreachable("-if rule will be evaluated separately, not here.");
}
+ } else if (rule instanceof ProguardIfRule) {
+ throw new Unreachable("-if rule will be evaluated separately, not here.");
} else if (rule instanceof ProguardCheckDiscardRule) {
if (memberKeepRules.isEmpty()) {
markClass(clazz, rule);
} else {
- markMatchingFields(clazz, memberKeepRules, rule, clazz);
- markMatchingMethods(clazz, memberKeepRules, rule, clazz);
+ preconditionSupplier = ImmutableMap.of((definition -> true), clazz);
+ markMatchingFields(clazz, memberKeepRules, rule, preconditionSupplier);
+ markMatchingMethods(clazz, memberKeepRules, rule, preconditionSupplier);
}
} else if (rule instanceof ProguardWhyAreYouKeepingRule
|| rule instanceof ProguardKeepPackageNamesRule) {
@@ -344,6 +358,19 @@
// -keep rule may vary (due to back references). So, we need to try all pairs of -if rule
// and live types.
for (DexType currentLiveType : liveTypes) {
+ DexClass currentLiveClass = appInfo.definitionFor(currentLiveType);
+ if (currentLiveClass == null) {
+ continue;
+ }
+ if (!satisfyClassType(rule, currentLiveClass)) {
+ continue;
+ }
+ if (!satisfyAccessFlag(rule, currentLiveClass)) {
+ continue;
+ }
+ if (!satisfyAnnotation(rule, currentLiveClass)) {
+ continue;
+ }
if (ifRule.hasInheritanceClassName()) {
if (!satisfyInheritanceRule(currentLiveType, definitionForWithLiveTypes, ifRule)) {
// Try another live type since the current one doesn't satisfy the inheritance rule.
@@ -406,20 +433,44 @@
} finally {
application.timing.end();
}
- return new ConsequentRootSet(noShrinking, noOptimization, noObfuscation);
+ return new ConsequentRootSet(noShrinking, noOptimization, noObfuscation, dependentNoShrinking);
+ }
+
+ private static DexDefinition testAndGetPrecondition(
+ DexDefinition definition, Map<Predicate<DexDefinition>, DexDefinition> preconditionSupplier) {
+ if (preconditionSupplier == null) {
+ return null;
+ }
+ DexDefinition precondition = null;
+ boolean conditionEverMatched = false;
+ for (Entry<Predicate<DexDefinition>, DexDefinition> entry : preconditionSupplier.entrySet()) {
+ if (entry.getKey().test(definition)) {
+ precondition = entry.getValue();
+ conditionEverMatched = true;
+ break;
+ }
+ }
+ // If precondition-supplier is given, there should be at least one predicate that holds.
+ // Actually, there should be only one predicate as we break the loop when it is found.
+ assert conditionEverMatched;
+ return precondition;
}
private void markMatchingVisibleMethods(
DexClass clazz,
Collection<ProguardMemberRule> memberKeepRules,
ProguardConfigurationRule rule,
- DexClass onlyIfClassKept) {
+ Map<Predicate<DexDefinition>, DexDefinition> preconditionSupplier) {
Set<Wrapper<DexMethod>> methodsMarked = new HashSet<>();
- Arrays.stream(clazz.directMethods()).forEach(method ->
- markMethod(method, memberKeepRules, methodsMarked, rule, onlyIfClassKept));
+ Arrays.stream(clazz.directMethods()).forEach(method -> {
+ DexDefinition precondition = testAndGetPrecondition(method, preconditionSupplier);
+ markMethod(method, memberKeepRules, methodsMarked, rule, precondition);
+ });
while (clazz != null) {
- Arrays.stream(clazz.virtualMethods()).forEach(method ->
- markMethod(method, memberKeepRules, methodsMarked, rule, onlyIfClassKept));
+ Arrays.stream(clazz.virtualMethods()).forEach(method -> {
+ DexDefinition precondition = testAndGetPrecondition(method, preconditionSupplier);
+ markMethod(method, memberKeepRules, methodsMarked, rule, precondition);
+ });
clazz = clazz.superType == null ? null : application.definitionFor(clazz.superType);
}
}
@@ -428,19 +479,22 @@
DexClass clazz,
Collection<ProguardMemberRule> memberKeepRules,
ProguardConfigurationRule rule,
- DexClass onlyIfClassKept) {
- Arrays.stream(clazz.directMethods()).forEach(method ->
- markMethod(method, memberKeepRules, null, rule, onlyIfClassKept));
- Arrays.stream(clazz.virtualMethods()).forEach(method ->
- markMethod(method, memberKeepRules, null, rule, onlyIfClassKept));
+ Map<Predicate<DexDefinition>, DexDefinition> preconditionSupplier) {
+ clazz.forEachMethod(method -> {
+ DexDefinition precondition = testAndGetPrecondition(method, preconditionSupplier);
+ markMethod(method, memberKeepRules, null, rule, precondition);
+ });
}
private void markMatchingFields(
DexClass clazz,
Collection<ProguardMemberRule> memberKeepRules,
ProguardConfigurationRule rule,
- DexClass onlyIfClassKept) {
- clazz.forEachField(field -> markField(field, memberKeepRules, rule, onlyIfClassKept));
+ Map<Predicate<DexDefinition>, DexDefinition> preconditionSupplier) {
+ clazz.forEachField(field -> {
+ DexDefinition precondition = testAndGetPrecondition(field, preconditionSupplier);
+ markField(field, memberKeepRules, rule, precondition);
+ });
}
// TODO(67934426): Test this code.
@@ -496,6 +550,19 @@
out.close();
}
+ private static boolean satisfyClassType(ProguardConfigurationRule rule, DexClass clazz) {
+ return rule.getClassType().matches(clazz) != rule.getClassTypeNegated();
+ }
+
+ private static boolean satisfyAccessFlag(ProguardConfigurationRule rule, DexClass clazz) {
+ return rule.getClassAccessFlags().containsAll(clazz.accessFlags)
+ && rule.getNegatedClassAccessFlags().containsNone(clazz.accessFlags);
+ }
+
+ private static boolean satisfyAnnotation(ProguardConfigurationRule rule, DexClass clazz) {
+ return containsAnnotation(rule.getClassAnnotation(), clazz.annotations);
+ }
+
private boolean satisfyInheritanceRule(
DexType type,
Function<DexType, DexClass> definitionFor,
@@ -794,6 +861,15 @@
this.ifRules = Collections.unmodifiableSet(ifRules);
}
+ // Add dependent items that depend on -if rules.
+ void addDependentItems(
+ Map<DexDefinition, Map<DexDefinition, ProguardKeepRule>> dependentItems) {
+ dependentItems.forEach((def, dependence) -> {
+ dependentNoShrinking.computeIfAbsent(def, x -> new IdentityHashMap<>())
+ .putAll(dependence);
+ });
+ }
+
Map<DexDefinition, ProguardKeepRule> getDependentItems(DexDefinition item) {
return Collections
.unmodifiableMap(dependentNoShrinking.getOrDefault(item, Collections.emptyMap()));
@@ -831,14 +907,17 @@
final Map<DexDefinition, ProguardKeepRule> noShrinking;
final Set<DexDefinition> noOptimization;
final Set<DexDefinition> noObfuscation;
+ final Map<DexDefinition, Map<DexDefinition, ProguardKeepRule>> dependentNoShrinking;
private ConsequentRootSet(
Map<DexDefinition, ProguardKeepRule> noShrinking,
Set<DexDefinition> noOptimization,
- Set<DexDefinition> noObfuscation) {
+ Set<DexDefinition> noObfuscation,
+ Map<DexDefinition, Map<DexDefinition, ProguardKeepRule>> dependentNoShrinking) {
this.noShrinking = Collections.unmodifiableMap(noShrinking);
this.noOptimization = Collections.unmodifiableSet(noOptimization);
this.noObfuscation = Collections.unmodifiableSet(noObfuscation);
+ this.dependentNoShrinking = Collections.unmodifiableMap(dependentNoShrinking);
}
}
}
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAccessModifierTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAccessModifierTest.java
index af9cfdf..e6de7cc 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAccessModifierTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAccessModifierTest.java
@@ -52,6 +52,33 @@
}
@Test
+ public void ifOnPublic_noPublicClassForIfRule() throws Exception {
+ List<String> config = ImmutableList.of(
+ "-repackageclasses 'top'",
+ "-keep class **.Main* {",
+ " public static void callIfNonPublic();",
+ "}",
+ "-if public class **.ClassForIf {",
+ " <methods>;",
+ "}",
+ "-keep,allowobfuscation class **.ClassForSubsequent {",
+ " public <methods>;",
+ "}"
+ );
+ CodeInspector codeInspector = inspectAfterShrinking(shrinker, CLASSES, config);
+ ClassSubject classSubject = codeInspector.clazz(ClassForIf.class);
+ assertThat(classSubject, isPresent());
+ MethodSubject methodSubject = classSubject.method(publicMethod);
+ assertThat(methodSubject, not(isPresent()));
+ methodSubject = classSubject.method(nonPublicMethod);
+ assertThat(methodSubject, isPresent());
+ assertFalse(methodSubject.getMethod().accessFlags.isPublic());
+
+ classSubject = codeInspector.clazz(ClassForSubsequent.class);
+ assertThat(classSubject, not(isPresent()));
+ }
+
+ @Test
public void ifOnNonPublic_keepOnPublic() throws Exception {
List<String> config = ImmutableList.of(
"-printmapping",
@@ -191,12 +218,12 @@
methodSubject = classSubject.method(publicMethod);
assertThat(methodSubject, not(isPresent()));
methodSubject = classSubject.method(nonPublicMethod);
+ assertThat(methodSubject, isPresent());
if (isR8(shrinker)) {
- // TODO(b/72109068): if kept in the 1st tree shaking, should be kept after publicizing.
- assertThat(methodSubject, not(isPresent()));
+ // TODO(b/72109068): if kept in the 1st tree shaking, should not be publicized.
+ assertTrue(methodSubject.getMethod().accessFlags.isPublic());
return;
}
- assertThat(methodSubject, isPresent());
assertFalse(methodSubject.getMethod().accessFlags.isPublic());
}
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAnnotationTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAnnotationTest.java
index ce2992a..00cb62e 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAnnotationTest.java
@@ -8,7 +8,6 @@
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.List;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -84,7 +83,6 @@
UsedAnnotation.class, UsedAnnotationDependent.class);
}
- @Ignore("b/116092333")
@Test
public void ifOnAnnotation_onDependentClass_withNthWildcard() throws Exception {
List<String> config = ImmutableList.of(
diff --git a/src/test/java/com/android/tools/r8/shaking/keepclassmembers/b115867670/B115867670.java b/src/test/java/com/android/tools/r8/shaking/keepclassmembers/b115867670/B115867670.java
index 30a9de9..bdd8e1a 100644
--- a/src/test/java/com/android/tools/r8/shaking/keepclassmembers/b115867670/B115867670.java
+++ b/src/test/java/com/android/tools/r8/shaking/keepclassmembers/b115867670/B115867670.java
@@ -18,7 +18,6 @@
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.List;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -127,6 +126,20 @@
}
@Test
+ public void testDependentWithKeepClass() throws Exception {
+ runTest(
+ "-keep @" + pkg + ".JsonClass class ** { <fields>; }",
+ this::checkKeepClassMembers);
+ }
+
+ @Test
+ public void testDependentWithKeepClassAllowObfuscation() throws Exception {
+ runTest(
+ "-keep,allowobfuscation @" + pkg + ".JsonClass class ** { <fields>; }",
+ this::checkKeepClassMembersRenamed);
+ }
+
+ @Test
public void testDependentWithKeepClassMembers() throws Exception {
runTest(
"-keepclassmembers @" + pkg + ".JsonClass class ** { <fields>; }",
@@ -141,7 +154,6 @@
}
@Test
- @Ignore("b/116092333")
public void testDependentWithIfKeepClassMembers() throws Exception {
runTest(
"-if @" + pkg + ".JsonClass class * -keepclassmembers class <1> { <fields>; }",
@@ -149,7 +161,6 @@
}
@Test
- @Ignore("b/116092333")
public void testDependentWithIfKeepClassMembersAllowObfuscation() throws Exception {
runTest(
"-if @"