Merge "Parse optional arguments, followed by arobase include."
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index ab88150..5f2e41c 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -212,7 +212,7 @@
     }
     // No Proguard rule could replace the instruction check for knowledge about the return value.
     DexEncodedMethod target = current.lookupSingleTarget(appView.appInfo(), callingContext);
-    if (target == null) {
+    if (target == null || appView.appInfo().neverPropagateValue.contains(target.method)) {
       return;
     }
     if (target.getOptimizationInfo().neverReturnsNull()
@@ -262,7 +262,7 @@
 
     // TODO(b/123857022): Should be able to use definitionFor().
     DexEncodedField target = appView.appInfo().lookupStaticTarget(field.getHolder(), field);
-    if (target == null) {
+    if (target == null || appView.appInfo().neverPropagateValue.contains(target.field)) {
       return;
     }
     // Check if a this value is known const.
@@ -326,8 +326,11 @@
         current.isInstancePut()
             ? appView.appInfo().lookupInstanceTarget(field.getHolder(), field)
             : appView.appInfo().lookupStaticTarget(field.getHolder(), field);
+    if (target == null || appView.appInfo().neverPropagateValue.contains(target.field)) {
+      return;
+    }
     // TODO(b/123857022): Should be possible to use `!isFieldRead(field)`.
-    if (target != null && !appView.appInfo().isFieldRead(target.field)) {
+    if (!appView.appInfo().isFieldRead(target.field)) {
       // Remove writes to dead (i.e. never read) fields.
       iterator.removeOrReplaceByDebugLocalRead();
     }
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 ef8b5f9..bbca1f1 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -2117,6 +2117,11 @@
      */
     public final Set<DexType> neverMerge;
     /**
+     * All methods and fields whose value *must* never be propagated due to a configuration
+     * directive. (testing only).
+     */
+    public final Set<DexReference> neverPropagateValue;
+    /**
      * All items with -identifiernamestring rule.
      * Bound boolean value indicates the rule is explicitly specified by users (<code>true</code>)
      * or not, i.e., implicitly added by R8 (<code>false</code>).
@@ -2195,6 +2200,7 @@
       this.keepUnusedArguments = enqueuer.rootSet.keepUnusedArguments;
       this.neverClassInline = enqueuer.rootSet.neverClassInline;
       this.neverMerge = enqueuer.rootSet.neverMerge;
+      this.neverPropagateValue = enqueuer.rootSet.neverPropagateValue;
       this.identifierNameStrings = joinIdentifierNameStrings(
           enqueuer.rootSet.identifierNameStrings, enqueuer.identifierNameStrings);
       this.prunedTypes = Collections.emptySet();
@@ -2252,6 +2258,7 @@
       this.keepUnusedArguments = previous.keepUnusedArguments;
       this.neverClassInline = previous.neverClassInline;
       this.neverMerge = previous.neverMerge;
+      this.neverPropagateValue = previous.neverPropagateValue;
       this.identifierNameStrings = previous.identifierNameStrings;
       this.prunedTypes =
           removedClasses == null
@@ -2336,6 +2343,8 @@
               .collect(Collectors.toList()));
       this.neverClassInline = rewriteItems(previous.neverClassInline, lense::lookupType);
       this.neverMerge = rewriteItems(previous.neverMerge, lense::lookupType);
+      this.neverPropagateValue =
+          lense.rewriteReferencesConservatively(previous.neverPropagateValue);
       this.identifierNameStrings =
           lense.rewriteReferencesConservatively(previous.identifierNameStrings);
       // Switchmap classes should never be affected by renaming.
@@ -2392,6 +2401,7 @@
       this.keepUnusedArguments = previous.keepUnusedArguments;
       this.neverClassInline = previous.neverClassInline;
       this.neverMerge = previous.neverMerge;
+      this.neverPropagateValue = previous.neverPropagateValue;
       this.identifierNameStrings = previous.identifierNameStrings;
       this.prunedTypes = previous.prunedTypes;
       this.switchMaps = switchMaps;
diff --git a/src/main/java/com/android/tools/r8/shaking/MemberValuePropagationRule.java b/src/main/java/com/android/tools/r8/shaking/MemberValuePropagationRule.java
new file mode 100644
index 0000000..dde4631
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/shaking/MemberValuePropagationRule.java
@@ -0,0 +1,84 @@
+// 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.shaking;
+
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.position.Position;
+import java.util.List;
+
+public class MemberValuePropagationRule extends ProguardConfigurationRule {
+
+  public enum Type {
+    NEVER
+  }
+
+  public static class Builder
+      extends ProguardConfigurationRule.Builder<MemberValuePropagationRule, Builder> {
+
+    private Builder() {
+      super();
+    }
+
+    Type type;
+
+    @Override
+    public Builder self() {
+      return this;
+    }
+
+    public Builder setType(Type type) {
+      this.type = type;
+      return this;
+    }
+
+    @Override
+    public MemberValuePropagationRule build() {
+      return new MemberValuePropagationRule(origin, getPosition(), source, classAnnotation,
+          classAccessFlags, negatedClassAccessFlags, classTypeNegated, classType, classNames,
+          inheritanceAnnotation, inheritanceClassName, inheritanceIsExtends, memberRules, type);
+    }
+  }
+
+  private final Type type;
+
+  private MemberValuePropagationRule(
+      Origin origin,
+      Position position,
+      String source,
+      ProguardTypeMatcher classAnnotation,
+      ProguardAccessFlags classAccessFlags,
+      ProguardAccessFlags negatedClassAccessFlags,
+      boolean classTypeNegated,
+      ProguardClassType classType,
+      ProguardClassNameList classNames,
+      ProguardTypeMatcher inheritanceAnnotation,
+      ProguardTypeMatcher inheritanceClassName,
+      boolean inheritanceIsExtends,
+      List<ProguardMemberRule> memberRules,
+      Type type) {
+    super(origin, position, source, classAnnotation, classAccessFlags, negatedClassAccessFlags,
+        classTypeNegated, classType, classNames, inheritanceAnnotation, inheritanceClassName,
+        inheritanceIsExtends, memberRules);
+    this.type = type;
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public Type getType() {
+    return type;
+  }
+
+  @Override
+  String typeString() {
+    switch (type) {
+      case NEVER:
+        return "neverpropagatevalue";
+    }
+    throw new Unreachable("Unknown member value propagation type " + type);
+  }
+
+}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index 5681566..9f7d021 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -382,6 +382,10 @@
       } else if (allowTestOptions && acceptString("nevermerge")) {
         ClassMergingRule rule = parseClassMergingRule(ClassMergingRule.Type.NEVER, optionStart);
         configurationBuilder.addRule(rule);
+      } else if (allowTestOptions && acceptString("neverpropagatevalue")) {
+        MemberValuePropagationRule rule =
+            parseMemberValuePropagationRule(MemberValuePropagationRule.Type.NEVER, optionStart);
+        configurationBuilder.addRule(rule);
       } else if (acceptString("useuniqueclassmembernames")) {
         configurationBuilder.setUseUniqueClassMemberNames(true);
       } else if (acceptString("adaptclassstrings")) {
@@ -650,6 +654,18 @@
       return keepRuleBuilder.build();
     }
 
+    private MemberValuePropagationRule parseMemberValuePropagationRule(
+        MemberValuePropagationRule.Type type, Position start)
+        throws ProguardRuleParserException {
+      MemberValuePropagationRule .Builder keepRuleBuilder =
+          MemberValuePropagationRule.builder().setOrigin(origin).setStart(start).setType(type);
+      parseClassSpec(keepRuleBuilder, false);
+      Position end = getPosition();
+      keepRuleBuilder.setSource(getSourceSnippet(contents, start, end));
+      keepRuleBuilder.setEnd(end);
+      return keepRuleBuilder.build();
+    }
+
     private InlineRule parseInlineRule(InlineRule.Type type, Position start)
         throws ProguardRuleParserException {
       InlineRule.Builder keepRuleBuilder = InlineRule.builder()
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 e27799a..2b1a6cd 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
@@ -80,6 +80,7 @@
   private final Set<DexMethod> keepUnusedArguments = Sets.newIdentityHashSet();
   private final Set<DexType> neverClassInline = Sets.newIdentityHashSet();
   private final Set<DexType> neverMerge = Sets.newIdentityHashSet();
+  private final Set<DexReference> neverPropagateValue = Sets.newIdentityHashSet();
   private final Map<DexReference, Map<DexReference, Set<ProguardKeepRule>>> dependentNoShrinking =
       new IdentityHashMap<>();
   private final Map<DexReference, ProguardMemberRule> mayHaveSideEffects = new IdentityHashMap<>();
@@ -201,6 +202,9 @@
         if (allRulesSatisfied(memberKeepRules, clazz)) {
           markClass(clazz, rule);
         }
+      } else if (rule instanceof MemberValuePropagationRule) {
+        markMatchingVisibleMethods(clazz, memberKeepRules, rule, null, true);
+        markMatchingVisibleFields(clazz, memberKeepRules, rule, null, true);
       } else if (rule instanceof ProguardAssumeValuesRule) {
         markMatchingVisibleMethods(clazz, memberKeepRules, rule, null, true);
         markMatchingVisibleFields(clazz, memberKeepRules, rule, null, true);
@@ -275,6 +279,7 @@
         keepUnusedArguments,
         neverClassInline,
         neverMerge,
+        neverPropagateValue,
         mayHaveSideEffects,
         noSideEffects,
         assumedValues,
@@ -993,6 +998,18 @@
         default:
           throw new Unreachable();
       }
+    } else if (context instanceof MemberValuePropagationRule) {
+      switch (((MemberValuePropagationRule) context).getType()) {
+        case NEVER:
+          if (item.isDexEncodedField()) {
+            neverPropagateValue.add(item.asDexEncodedField().field);
+          } else if (item.isDexEncodedMethod()) {
+            neverPropagateValue.add(item.asDexEncodedMethod().method);
+          }
+          break;
+        default:
+          throw new Unreachable();
+      }
     } else if (context instanceof ProguardIdentifierNameStringRule) {
       if (item.isDexEncodedField()) {
         identifierNameStrings.add(item.asDexEncodedField().field);
@@ -1025,6 +1042,7 @@
     public final Set<DexMethod> keepUnusedArguments;
     public final Set<DexType> neverClassInline;
     public final Set<DexType> neverMerge;
+    public final Set<DexReference> neverPropagateValue;
     public final Map<DexReference, ProguardMemberRule> mayHaveSideEffects;
     public final Map<DexReference, ProguardMemberRule> noSideEffects;
     public final Map<DexReference, ProguardMemberRule> assumedValues;
@@ -1047,6 +1065,7 @@
         Set<DexMethod> keepUnusedArguments,
         Set<DexType> neverClassInline,
         Set<DexType> neverMerge,
+        Set<DexReference> neverPropagateValue,
         Map<DexReference, ProguardMemberRule> mayHaveSideEffects,
         Map<DexReference, ProguardMemberRule> noSideEffects,
         Map<DexReference, ProguardMemberRule> assumedValues,
@@ -1066,6 +1085,7 @@
       this.keepUnusedArguments = keepUnusedArguments;
       this.neverClassInline = neverClassInline;
       this.neverMerge = Collections.unmodifiableSet(neverMerge);
+      this.neverPropagateValue = neverPropagateValue;
       this.mayHaveSideEffects = mayHaveSideEffects;
       this.noSideEffects = noSideEffects;
       this.assumedValues = assumedValues;
@@ -1090,6 +1110,8 @@
           lense.rewriteMutableMethodsConservatively(previous.keepUnusedArguments);
       this.neverClassInline = lense.rewriteMutableTypesConservatively(previous.neverClassInline);
       this.neverMerge = lense.rewriteTypesConservatively(previous.neverMerge);
+      this.neverPropagateValue =
+          lense.rewriteMutableReferencesConservatively(previous.neverPropagateValue);
       this.mayHaveSideEffects =
           rewriteMutableReferenceKeys(previous.mayHaveSideEffects, lense::lookupReference);
       this.noSideEffects =
diff --git a/src/test/java/com/android/tools/r8/NeverPropagateValue.java b/src/test/java/com/android/tools/r8/NeverPropagateValue.java
new file mode 100644
index 0000000..ac33c46
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/NeverPropagateValue.java
@@ -0,0 +1,10 @@
+// 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;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD, ElementType.FIELD})
+public @interface NeverPropagateValue {}
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 01b6cee..8edbb41 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -44,6 +44,7 @@
   private boolean enableInliningAnnotations = false;
   private boolean enableClassInliningAnnotations = false;
   private boolean enableMergeAnnotations = false;
+  private boolean enableMemberValuePropagationAnnotations = false;
   private boolean enableConstantArgumentAnnotations = false;
   private boolean enableUnusedArgumentAnnotations = false;
   private boolean enableSideEffectAnnotations = false;
@@ -64,6 +65,7 @@
     if (enableInliningAnnotations
         || enableClassInliningAnnotations
         || enableMergeAnnotations
+        || enableMemberValuePropagationAnnotations
         || enableConstantArgumentAnnotations
         || enableUnusedArgumentAnnotations
         || enableSideEffectAnnotations) {
@@ -195,6 +197,15 @@
     return self();
   }
 
+  public R8TestBuilder enableMemberValuePropagationAnnotations() {
+    if (!enableMemberValuePropagationAnnotations) {
+      enableMemberValuePropagationAnnotations = true;
+      addInternalKeepRules(
+          "-neverpropagatevalue class * { @com.android.tools.r8.NeverPropagateValue *; }");
+    }
+    return self();
+  }
+
   public R8TestBuilder enableSideEffectAnnotations() {
     if (!enableSideEffectAnnotations) {
       enableSideEffectAnnotations = true;
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/AccessRelaxationTestBase.java b/src/test/java/com/android/tools/r8/accessrelaxation/AccessRelaxationTestBase.java
index abd1b5f..11d1ed2 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/AccessRelaxationTestBase.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/AccessRelaxationTestBase.java
@@ -6,14 +6,10 @@
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPublic;
 import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
 
-import com.android.tools.r8.R8Command;
 import com.android.tools.r8.TestBase;
-import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.naming.MemberNaming.MethodSignature;
-import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
@@ -26,33 +22,6 @@
     this.backend = backend;
   }
 
-  static R8Command.Builder loadProgramFiles(Backend backend, Iterable<Class> classes) {
-    R8Command.Builder builder = R8Command.builder();
-    for (Class clazz : classes) {
-      builder.addProgramFiles(ToolHelper.getClassFileForTestClass(clazz));
-    }
-    builder.setProgramConsumer(emptyConsumer(backend)).addLibraryFiles(runtimeJar(backend));
-    if (backend == Backend.DEX) {
-      builder.setMinApiLevel(ToolHelper.getMinApiLevelForDexVm().getLevel());
-    }
-    return builder;
-  }
-
-  void compareReferenceJVMAndProcessed(AndroidApp app, Class mainClass) throws Exception {
-    // Run on Jvm.
-    String jvmOutput = runOnJava(mainClass);
-    String output;
-    if (backend == Backend.DEX) {
-      output = runOnArt(app, mainClass);
-    } else {
-      assert backend == Backend.CF;
-      output = runOnJava(app, mainClass);
-    }
-    String adjustedOutput =
-        output.replace("java.lang.IncompatibleClassChangeError", "java.lang.IllegalAccessError");
-    assertEquals(jvmOutput, adjustedOutput);
-  }
-
   static void assertPublic(CodeInspector codeInspector, Class clazz, MethodSignature signature) {
     ClassSubject classSubject = codeInspector.clazz(clazz);
     assertThat(classSubject, isPresent());
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java
index 9df323a..3bdfa7e 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java
@@ -4,18 +4,14 @@
 package com.android.tools.r8.accessrelaxation;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
-import com.android.tools.r8.R8Command;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.R8TestRunResult;
+import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import java.util.List;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -158,9 +154,9 @@
 
 @RunWith(Parameterized.class)
 public final class ConstructorRelaxationTest extends AccessRelaxationTestBase {
-  private static final String INIT= "<init>";
-  private static final List<Class> CLASSES =
-      ImmutableList.of(L1.class, L2_1.class, L2_2.class, L3_1.class, L3_2.class);
+  private static final Class<?>[] CLASSES = {
+      L1.class, L2_1.class, L2_2.class, L3_1.class, L3_2.class
+  };
 
   @Parameterized.Parameters(name = "Backend: {0}")
   public static Backend[] data() {
@@ -173,11 +169,25 @@
 
   @Test
   public void test() throws Exception {
+    String expectedOutput =
+        StringUtils.lines(
+            "private_x",
+            "21_main_y",
+            "22_L2_1_y",
+            "31_L2_1_y_41",
+            "22_32_main_z");
     Class mainClass = CtorTestMain.class;
-    R8Command.Builder builder =
-        loadProgramFiles(backend, Iterables.concat(CLASSES, ImmutableList.of(mainClass)));
-    builder.addProguardConfiguration(
-        ImmutableList.of(
+
+    R8TestRunResult result =
+        testForR8(backend)
+            .addProgramClasses(mainClass)
+            .addProgramClasses(CLASSES)
+            .addOptionsModification(o -> {
+              o.enableInlining = false;
+              o.enableVerticalClassMerging = false;
+            })
+            .noMinification()
+        .addKeepRules(
             "-keep class " + mainClass.getCanonicalName() + "{",
             "  public static void main(java.lang.String[]);",
             "}",
@@ -186,21 +196,16 @@
             "  <init>(...);",
             "}",
             "",
-            "-dontobfuscate",
-            "-allowaccessmodification"
-        ),
-        Origin.unknown());
+            "-allowaccessmodification")
+        .run(mainClass);
 
-    AndroidApp app =
-        ToolHelper.runR8(
-            builder.build(),
-            options -> {
-              options.enableInlining = false;
-              options.enableVerticalClassMerging = false;
-            });
-    compareReferenceJVMAndProcessed(app, mainClass);
+    assertEquals(
+        expectedOutput,
+        result
+            .getStdOut()
+            .replace("java.lang.IncompatibleClassChangeError", "java.lang.IllegalAccessError"));
 
-    CodeInspector codeInspector = new CodeInspector(app);
+    CodeInspector codeInspector = result.inspector();
     for (Class clazz : CLASSES) {
       ClassSubject classSubject = codeInspector.clazz(clazz);
       assertThat(classSubject, isPresent());
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java
index 7ab3625..a6e1aa7 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java
@@ -73,6 +73,8 @@
     R8TestRunResult result =
         testForR8(backend)
             .addProgramFiles(ToolHelper.getClassFilesForTestPackage(mainClass.getPackage()))
+            .enableInliningAnnotations()
+            .enableMemberValuePropagationAnnotations()
             .addOptionsModification(o -> o.enableArgumentRemoval = enableArgumentRemoval)
             .noMinification()
             .addKeepRules(
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/A.java b/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/A.java
index 5337641..a05f41f 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/A.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/A.java
@@ -4,13 +4,17 @@
 
 package com.android.tools.r8.accessrelaxation.privatestatic;
 
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.NeverPropagateValue;
+
 public class A {
   public String foo() {
     return "A::foo()" + baz() + bar() + bar(0);
   }
 
-  // NOTE: here and below 'synchronized' is supposed to disable inlining of this method.
-  private synchronized static String baz() {
+  @NeverInline
+  @NeverPropagateValue
+  private static String baz() {
     return "A::baz()";
   }
 
@@ -18,7 +22,9 @@
     return baz();
   }
 
-  private synchronized static String bar() {
+  @NeverInline
+  @NeverPropagateValue
+  private static String bar() {
     return "A::bar()";
   }
 
@@ -26,7 +32,9 @@
     return bar();
   }
 
-  private synchronized static String bar(int i) {
+  @NeverInline
+  @NeverPropagateValue
+  private static String bar(int i) {
     return "A::bar(int)";
   }
 
@@ -34,7 +42,9 @@
     return bar(1);
   }
 
-  private synchronized static String blah(int i) {
+  @NeverInline
+  @NeverPropagateValue
+  private static String blah(int i) {
     return "A::blah(int)";
   }
 
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/B.java b/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/B.java
index b0518df..33b132f 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/B.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/B.java
@@ -4,6 +4,9 @@
 
 package com.android.tools.r8.accessrelaxation.privatestatic;
 
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.NeverPropagateValue;
+
 public class B extends A implements I {
   public String bar() {
     try {
@@ -13,7 +16,9 @@
     }
   }
 
-  private synchronized static String blah(int i) {
+  @NeverInline
+  @NeverPropagateValue
+  private static String blah(int i) {
     return "B::blah(int)";
   }
 
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/BB.java b/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/BB.java
index 0887714..01ec674 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/BB.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/BB.java
@@ -4,8 +4,13 @@
 
 package com.android.tools.r8.accessrelaxation.privatestatic;
 
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.NeverPropagateValue;
+
 public class BB extends A {
-  private synchronized static String blah(int i) {
+  @NeverInline
+  @NeverPropagateValue
+  private static String blah(int i) {
     return "BB::blah(int)";
   }