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 1d9de37..492f1f5 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -1045,6 +1045,8 @@
             ruleBuilder.setRuleType(ProguardMemberType.ALL);
           } else {
             if (hasNextChar('(')) {
+              // Parsing "<init>" is already done, and thus neither '<' nor '>' can appear.
+              checkConstructorPattern(first, firstStart);
               ruleBuilder.setRuleType(ProguardMemberType.CONSTRUCTOR);
               ruleBuilder.setName(first);
               ruleBuilder.setArguments(parseArgumentList());
@@ -1055,6 +1057,10 @@
               if (second != null) {
                 skipWhitespace();
                 if (hasNextChar('(')) {
+                  // Neither '<' nor '>' can appear except for "[access-flag]* void <init>(...)".
+                  if (!first.pattern.contains("void") || !second.pattern.equals("<init>")) {
+                    checkConstructorPattern(second, secondStart);
+                  }
                   ruleBuilder.setRuleType(ProguardMemberType.METHOD);
                   ruleBuilder.setName(second);
                   ruleBuilder
@@ -1140,6 +1146,18 @@
       }
     }
 
+    private void checkConstructorPattern(
+        IdentifierPatternWithWildcards pattern, TextPosition position)
+        throws ProguardRuleParserException {
+      if (pattern.pattern.contains("<")) {
+        throw parseError("Unexpected character '<' in method name. "
+            + "The character '<' is only allowed in the method name '<init>'.", position);
+      } else if (pattern.pattern.contains(">")) {
+        throw parseError("Unexpected character '>' in method name. "
+            + "The character '>' is only allowed in the method name '<init>'.", position);
+      }
+    }
+
     private List<ProguardTypeMatcher> parseArgumentList() throws ProguardRuleParserException {
       List<ProguardTypeMatcher> arguments = new ArrayList<>();
       skipWhitespace();
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
index 62aaf50..d0fb723 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -5,6 +5,7 @@
 
 import static com.android.tools.r8.DiagnosticsChecker.checkDiagnostics;
 import static com.android.tools.r8.shaking.ProguardConfigurationSourceStrings.createConfigurationForTesting;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.StringContains.containsString;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -12,7 +13,6 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -27,6 +27,7 @@
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.position.TextRange;
 import com.android.tools.r8.shaking.ProguardConfigurationParser.IdentifierPatternWithWildcards;
+import com.android.tools.r8.shaking.constructor.InitMatchingTest;
 import com.android.tools.r8.utils.AbortException;
 import com.android.tools.r8.utils.FileUtils;
 import com.android.tools.r8.utils.InternalOptions.PackageObfuscationMode;
@@ -2381,6 +2382,12 @@
     return parser.getConfig();
   }
 
+  private ProguardConfiguration parseAndVerifyParserEndsCleanly(Path config) {
+    parser.parse(config);
+    verifyParserEndsCleanly();
+    return parser.getConfig();
+  }
+
   private void verifyParserEndsCleanly() {
     assertEquals(0, handler.infos.size());
     assertEquals(0, handler.warnings.size());
@@ -2538,4 +2545,44 @@
               + "The negation character can only be used to negate access flags");
     }
   }
+
+  @Test
+  public void b130710288() throws Exception {
+    // "[[access-flag]* void] <init>" is the only valid format.
+    for (String initName : ImmutableList.of("<init>", "void <init>", "public void <init>")) {
+      Path initConfig = writeTextToTempFile(
+          "-keep class **.MyClass {",
+          "  " + initName + "(...);",
+          "}");
+      parseAndVerifyParserEndsCleanly(initConfig);
+    }
+
+    for (String initName : InitMatchingTest.INIT_NAMES) {
+      // Tested above.
+      if (initName.contains("<init>")) {
+        continue;
+      }
+      reset();
+      Path proguardConfig = writeTextToTempFile(
+          "-keep class **.MyClass {",
+          "  " + initName + "(...);",
+          "}");
+      try {
+        parser.parse(proguardConfig);
+        fail("Expect to fail due to unsupported constructor name pattern.");
+      } catch (AbortException e) {
+        int column = initName.contains("void") ? initName.indexOf("void") + 8 : 3;
+        checkDiagnostics(
+            handler.errors, proguardConfig, 2, column, "Unexpected character", "method name");
+      }
+      // For some exceptional cases, Proguard accepts the rules but fails with an empty jar message.
+      if (initName.contains("<init>")
+          || initName.contains("<clinit>")
+          || initName.contains("void")) {
+        continue;
+      }
+      verifyFailWithProguard6(
+          proguardConfig, "Expecting type and name instead of just '" + initName + "'");
+    }
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/shaking/constructor/InitMatchingTest.java b/src/test/java/com/android/tools/r8/shaking/constructor/InitMatchingTest.java
new file mode 100644
index 0000000..4db8a60
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/constructor/InitMatchingTest.java
@@ -0,0 +1,136 @@
+// 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.constructor;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.ProguardTestCompileResult;
+import com.android.tools.r8.R8TestCompileResult;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.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;
+
+class InitMatchingTestClass {
+  // Trivial <clinit>
+  static {
+  }
+  int field;
+  public InitMatchingTestClass(int arg) {
+    field = arg;
+  }
+}
+
+@RunWith(Parameterized.class)
+public class InitMatchingTest extends TestBase {
+  public static final List<String> INIT_NAMES = ImmutableList.of(
+      "<clinit>", "<init>", "<*init>", "<in*>", "<in*", "*init>",
+      "void <clinit>", "void <init>", "void <*init>", "void <in*>", "void <in*", "void *init>",
+      "public void <init>", "public void <*init>"
+  );
+
+  @Parameterized.Parameters(name = "{0} \"{1}\"")
+  public static Collection<Object[]> data() {
+    return buildParameters(ToolHelper.getBackends(), INIT_NAMES);
+  }
+
+  private final Backend backend;
+  private final String initName;
+
+  public InitMatchingTest(Backend backend, String initName) {
+    this.backend = backend;
+    this.initName = initName;
+  }
+
+  private String createKeepRule() {
+    return "-keep class * { " + initName + "(...); }";
+  }
+
+  @Test
+  public void testProguard() throws Exception {
+    assumeTrue(backend == Backend.CF);
+    ProguardTestCompileResult result;
+    try {
+      result =
+        testForProguard()
+            .addProgramClasses(InitMatchingTestClass.class)
+            .addKeepRules(createKeepRule())
+            .compile();
+    } catch (CompilationFailedException e) {
+      assertNotEquals("<init>", initName);
+      if (initName.equals("void <in*")) {
+        assertThat(e.getMessage(), containsString("Missing closing angular bracket"));
+      } else {
+        assertThat(e.getMessage(),
+            containsString("Expecting type and name instead of just '" + initName + "'"));
+      }
+      return;
+    }
+    result.inspect(this::inspectProguard);
+  }
+
+  private void inspectProguard(CodeInspector inspector) {
+    ClassSubject classSubject = inspector.clazz(InitMatchingTestClass.class);
+    assertThat(classSubject, isPresent());
+    MethodSubject init = classSubject.init(ImmutableList.of("int"));
+    if (initName.equals("void <clinit>")) {
+      assertThat(init, not(isPresent()));
+    } else {
+      assertThat(init, isPresent());
+    }
+    MethodSubject clinit = classSubject.clinit();
+    if (initName.equals("void <clinit>")
+        || initName.equals("void <*init>")
+        || initName.equals("void *init>")) {
+      assertThat(clinit, isPresent());
+    } else {
+      assertThat(clinit, not(isPresent()));
+    }
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    R8TestCompileResult result;
+    try {
+      result =
+        testForR8(backend)
+            .addProgramClasses(InitMatchingTestClass.class)
+            .addKeepRules(createKeepRule())
+            .compile();
+    } catch (CompilationFailedException e) {
+      assertNotEquals("<init>", initName);
+      assertThat(e.getCause().getMessage(),
+          containsString("Unexpected character '" + (initName.contains("<") ? "<" : ">") + "'"));
+      assertThat(e.getCause().getMessage(),
+          containsString("only allowed in the method name '<init>'"));
+      return;
+    }
+    result
+        .assertNoMessages()
+        .inspect(this::inspectR8);
+  }
+
+  private void inspectR8(CodeInspector inspector) {
+    ClassSubject classSubject = inspector.clazz(InitMatchingTestClass.class);
+    assertThat(classSubject, isPresent());
+    MethodSubject init = classSubject.init(ImmutableList.of("int"));
+    assertThat(init, isPresent());
+    MethodSubject clinit = classSubject.clinit();
+    assertThat(clinit, not(isPresent()));
+  }
+
+}
