Fix compiler crash due to accidental override in native JsType.

Bug: #9379
Bug-Link: https://github.com/gwtproject/gwt/issues/9379
Change-Id: I56319552d6a5cc58b3af93fe2d78c5093a226e34
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/JjsUtils.java b/dev/core/src/com/google/gwt/dev/jjs/impl/JjsUtils.java
index 59dc479..425d876 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/JjsUtils.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/JjsUtils.java
@@ -154,15 +154,22 @@
 
   /**
    * Creates a synthetic forwarding  stub in {@code type} with the same signature as
-   * {@code superTypeMethod} that dispatchs to that method..
+   * {@code superTypeMethod} that dispatchs to that method.
    */
   public static JMethod createForwardingMethod(JDeclaredType type,
       JMethod methodToDelegateTo) {
     JMethod forwardingMethod = createEmptyMethodFromExample(type, methodToDelegateTo, false);
     forwardingMethod.setForwarding();
 
-    if (methodToDelegateTo.isJsOverlay() && type.isJsNative()) {
-      forwardingMethod.isJsOverlay();
+    if (type.isJsNative()) {
+      if (methodToDelegateTo.isJsNative()) {
+        // Accidental override of native methods on native JsTypes are done by just redeclaring the
+        // native method.
+        return forwardingMethod;
+      }
+      // Otherwise the forwarding method is an overlay method with a proper body.
+      forwardingMethod.setJsOverlay();
+      forwardingMethod.setBody(new JMethodBody(methodToDelegateTo.getSourceInfo()));
     }
 
     // Create the forwarding body.
diff --git a/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java b/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
index 2dc6762..2529d6e 100644
--- a/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
+++ b/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
@@ -382,4 +382,42 @@
   public void testUnreferencedNativeArrayInstanceOf() {
     assertTrue(createArray() instanceof UnreferencedNativeType[]);
   }
+
+  @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
+  interface NativeInterface {
+    void add(String element);
+  }
+
+  @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
+  static class NativeSuperClass {
+    public native void add(String element);
+    public native boolean remove(String element);
+  }
+
+  @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
+  static class NativeSubClassAccidentalOverride
+      extends NativeSuperClass implements NativeInterface {
+  }
+
+  public native NativeSubClassAccidentalOverride createNativeSubclass() /*-{
+    return {
+        add:
+            function(e) {
+              this[0] = e;
+            },
+        remove:
+            function(e) {
+              var ret = this[0] == e;
+              this[0] = undefined;
+              return ret;
+            }
+      };
+  }-*/;
+
+  public void testForwaringMethodsOnNativeClasses() {
+    NativeSubClassAccidentalOverride subClass = createNativeSubclass();
+    subClass.add("Hi");
+    assertTrue(subClass.remove("Hi"));
+    assertFalse(subClass.remove("Hi"));
+  }
 }