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 @"