[vm/compiler] Do not use interface target for calls via getters

For calls via getters and fields front-end generates MethodInvocation
node with interface target pointing to a getter/field.
Such target doesn't fully represent what is being called - it should
be implicitly chained by call(), so it is incorrect to use such
interface target for type propagation.

Change-Id: I76198b443474fdcb383671fbc9946b4938a4e1df
Reviewed-on: https://dart-review.googlesource.com/c/88260
Auto-Submit: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index e9435cf..73ff36d 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -3639,13 +3639,13 @@
   const Function* interface_target = &Function::null_function();
   const NameIndex itarget_name =
       ReadCanonicalNameReference();  // read interface_target_reference.
-  if (!H.IsRoot(itarget_name) && !H.IsField(itarget_name)) {
+  if (!H.IsRoot(itarget_name) && !H.IsField(itarget_name) &&
+      !H.IsGetter(itarget_name)) {
     interface_target = &Function::ZoneHandle(
         Z, H.LookupMethodByMember(itarget_name,
                                   H.DartProcedureName(itarget_name)));
-    ASSERT((name.raw() == interface_target->name()) ||
-           (interface_target->IsGetterFunction() &&
-            Field::GetterSymbol(name) == interface_target->name()));
+    ASSERT(name.raw() == interface_target->name());
+    ASSERT(!interface_target->IsGetterFunction());
   }
 
   // TODO(sjindel): Avoid the check for null on unchecked closure calls if TFA
diff --git a/tests/language_2/vm/type_of_call_via_getter_test.dart b/tests/language_2/vm/type_of_call_via_getter_test.dart
new file mode 100644
index 0000000..bd246bb
--- /dev/null
+++ b/tests/language_2/vm/type_of_call_via_getter_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, the Dart 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.
+
+// This test verifies that compiler infers correct type from call via getter.
+
+// VMOptions=--no_background_compilation --optimization_counter_threshold=10
+
+import "package:expect/expect.dart";
+
+typedef String IntFunctionType(int _);
+
+String functionImpl(int a) => 'abc';
+
+class Box {
+  IntFunctionType get fun => functionImpl;
+}
+
+var box = new Box();
+
+void foo() {
+  Expect.isFalse(box.fun(42) is Function);
+  Expect.isTrue(box.fun(42) is String);
+}
+
+void main() {
+  for (int i = 0; i < 20; ++i) {
+    foo();
+  }
+}