diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 4bb9fb2..73f0611 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
 
   // This field is accessed from release scripts using simple pattern matching.
   // Therefore, changing this field could break our release scripts.
-  public static final String LABEL = "1.2.35";
+  public static final String LABEL = "1.2.36";
 
   private Version() {
   }
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 c4276dc..c4e6251 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -1194,6 +1194,7 @@
     private IdentifierPatternWithWildcards acceptIdentifierWithBackreference(IdentifierType kind) {
       ImmutableList.Builder<ProguardWildcard> wildcardsCollector = ImmutableList.builder();
       StringBuilder currentAsterisks = null;
+      int asteriskCount = 0;
       StringBuilder currentBackreference = null;
       skipWhitespace();
       int start = position;
@@ -1235,19 +1236,35 @@
           }
         } else if (currentAsterisks != null) {
           if (current == '*') {
+            // only '*', '**', and '***' are allowed.
+            // E.g., '****' should be regarded as two separate wildcards (e.g., '***' and '*')
+            if (asteriskCount >= 3) {
+              wildcardsCollector.add(new ProguardWildcard.Pattern(currentAsterisks.toString()));
+              currentAsterisks = new StringBuilder();
+              asteriskCount = 0;
+            }
             currentAsterisks.append((char) current);
+            asteriskCount++;
             end += Character.charCount(current);
             continue;
           } else {
             wildcardsCollector.add(new ProguardWildcard.Pattern(currentAsterisks.toString()));
             currentAsterisks = null;
+            asteriskCount = 0;
           }
         }
         // From now on, neither in asterisk collecting state nor back reference collecting state.
         assert currentAsterisks == null && currentBackreference == null;
         if (current == '*') {
-          currentAsterisks = new StringBuilder();
-          currentAsterisks.append((char) current);
+          if (kind == IdentifierType.CLASS_NAME) {
+            // '**' and '***' are only allowed in type name.
+            currentAsterisks = new StringBuilder();
+            currentAsterisks.append((char) current);
+            asteriskCount = 1;
+          } else {
+            // For member names, regard '**' or '***' as separate single-asterisk wildcards.
+            wildcardsCollector.add(new ProguardWildcard.Pattern(String.valueOf((char) current)));
+          }
           end += Character.charCount(current);
         } else if (current == '?' || current == '%') {
           wildcardsCollector.add(new ProguardWildcard.Pattern(String.valueOf((char) current)));
diff --git a/src/test/java/com/android/tools/r8/shaking/AsterisksTest.java b/src/test/java/com/android/tools/r8/shaking/AsterisksTest.java
new file mode 100644
index 0000000..8290521
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/AsterisksTest.java
@@ -0,0 +1,176 @@
+// Copyright (c) 2018, 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 static com.android.tools.r8.utils.DexInspectorMatchers.isPresent;
+import static com.android.tools.r8.utils.DexInspectorMatchers.isRenamed;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.naming.MemberNaming.MethodSignature;
+import com.android.tools.r8.shaking.forceproguardcompatibility.ProguardCompatabilityTestBase;
+import com.android.tools.r8.utils.DexInspector;
+import com.android.tools.r8.utils.DexInspector.ClassSubject;
+import com.android.tools.r8.utils.DexInspector.FieldSubject;
+import com.android.tools.r8.utils.DexInspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+class B111974287 {
+  B111974287 self;
+  B111974287[] clones;
+
+  B111974287() {
+    self = this;
+    clones = new B111974287[1];
+    clones[0] = self;
+  }
+
+  B111974287 fooX() {
+    System.out.println("fooX");
+    return self;
+  }
+
+  B111974287 fooYY() {
+    System.out.println("fooYY");
+    return self;
+  }
+
+  B111974287 fooZZZ() {
+    System.out.println("fooZZZ");
+    return self;
+  }
+}
+
+@RunWith(Parameterized.class)
+public class AsterisksTest extends ProguardCompatabilityTestBase {
+  private final static List<Class> CLASSES = ImmutableList.of(B111974287.class);
+  private final Shrinker shrinker;
+
+  public AsterisksTest(Shrinker shrinker) {
+    this.shrinker = shrinker;
+  }
+
+  @Parameters(name = "shrinker: {0}")
+  public static Collection<Object> data() {
+    return ImmutableList.of(Shrinker.PROGUARD6, Shrinker.R8);
+  }
+
+  @Test
+  public void doubleAsterisksInField() throws Exception {
+    List<String> config = ImmutableList.of(
+        "-keep class **." + B111974287.class.getSimpleName() + "{",
+        "  ** **;",
+        "}"
+    );
+    DexInspector codeInspector = runShrinker(shrinker, CLASSES, config);
+    ClassSubject classSubject = codeInspector.clazz(B111974287.class);
+    assertThat(classSubject, isPresent());
+    assertThat(classSubject, not(isRenamed()));
+    FieldSubject fieldSubject = classSubject.field(B111974287.class.getTypeName(), "self");
+    assertThat(fieldSubject, isPresent());
+    assertThat(fieldSubject, not(isRenamed()));
+    fieldSubject = classSubject.field(B111974287.class.getTypeName() + "[]", "clones");
+    // TODO(b/111974287): Proguard6 kept and renamed the field with array type.
+    if (shrinker == Shrinker.PROGUARD6) {
+      return;
+    }
+    assertThat(fieldSubject, not(isPresent()));
+  }
+
+  @Test
+  public void doubleAsterisksInMethod() throws Exception {
+    List<String> config = ImmutableList.of(
+        "-keep class **." + B111974287.class.getSimpleName() + "{",
+        "  ** foo**(...);",
+        "}"
+    );
+    DexInspector codeInspector = runShrinker(shrinker, CLASSES, config);
+    ClassSubject classSubject = codeInspector.clazz(B111974287.class);
+    assertThat(classSubject, isPresent());
+    assertThat(classSubject, not(isRenamed()));
+    DexClass clazz = classSubject.getDexClass();
+    assertEquals(3, clazz.virtualMethods().length);
+    for (DexEncodedMethod encodedMethod : clazz.virtualMethods()) {
+      assertTrue(encodedMethod.method.name.toString().startsWith("foo"));
+      MethodSubject methodSubject =
+          classSubject.method(MethodSignature.fromDexMethod(encodedMethod.method));
+      assertThat(methodSubject, isPresent());
+      assertThat(methodSubject, not(isRenamed()));
+    }
+  }
+
+  @Test
+  public void tripleAsterisksInField() throws Exception {
+    List<String> config = ImmutableList.of(
+        "-keep class **." + B111974287.class.getSimpleName() + "{",
+        "  *** ***;",
+        "}"
+    );
+    DexInspector codeInspector = runShrinker(shrinker, CLASSES, config);
+    ClassSubject classSubject = codeInspector.clazz(B111974287.class);
+    assertThat(classSubject, isPresent());
+    assertThat(classSubject, not(isRenamed()));
+    FieldSubject fieldSubject = classSubject.field(B111974287.class.getTypeName(), "self");
+    assertThat(fieldSubject, isPresent());
+    assertThat(fieldSubject, not(isRenamed()));
+    fieldSubject = classSubject.field(B111974287.class.getTypeName() + "[]", "clones");
+    assertThat(fieldSubject, isPresent());
+    assertThat(fieldSubject, not(isRenamed()));
+  }
+
+  @Test
+  public void tripleAsterisksInMethod() throws Exception {
+    List<String> config = ImmutableList.of(
+        "-keep class **." + B111974287.class.getSimpleName() + "{",
+        "  *** foo***(...);",
+        "}"
+    );
+    DexInspector codeInspector = runShrinker(shrinker, CLASSES, config);
+    ClassSubject classSubject = codeInspector.clazz(B111974287.class);
+    assertThat(classSubject, isPresent());
+    assertThat(classSubject, not(isRenamed()));
+    DexClass clazz = classSubject.getDexClass();
+    assertEquals(3, clazz.virtualMethods().length);
+    for (DexEncodedMethod encodedMethod : clazz.virtualMethods()) {
+      assertTrue(encodedMethod.method.name.toString().startsWith("foo"));
+      MethodSubject methodSubject =
+          classSubject.method(MethodSignature.fromDexMethod(encodedMethod.method));
+      assertThat(methodSubject, isPresent());
+      assertThat(methodSubject, not(isRenamed()));
+    }
+  }
+
+  @Test
+  public void quadrupleAsterisksInType() throws Exception {
+    List<String> config = ImmutableList.of(
+        "-keep class **** {",
+        "  **** foo***(...);",
+        "}"
+    );
+    DexInspector codeInspector = runShrinker(shrinker, CLASSES, config);
+    ClassSubject classSubject = codeInspector.clazz(B111974287.class);
+    assertThat(classSubject, isPresent());
+    assertThat(classSubject, not(isRenamed()));
+    DexClass clazz = classSubject.getDexClass();
+    assertEquals(3, clazz.virtualMethods().length);
+    for (DexEncodedMethod encodedMethod : clazz.virtualMethods()) {
+      assertTrue(encodedMethod.method.name.toString().startsWith("foo"));
+      MethodSubject methodSubject =
+          classSubject.method(MethodSignature.fromDexMethod(encodedMethod.method));
+      assertThat(methodSubject, isPresent());
+      assertThat(methodSubject, not(isRenamed()));
+    }
+  }
+
+}
