Version 2.14.0-311.0.dev

Merge commit '356472e221de889bd89a86926a13be7297151765' into 'dev'
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index b8033f9..002acc1 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -18,6 +18,7 @@
   Type applyCall(Call callSite, Selector selector, Args<Type> args,
       {bool isResultUsed});
   void typeCheckTriggered();
+  void addAllocatedClass(Class c);
 }
 
 /// Base class for all statements in a summary.
@@ -230,12 +231,16 @@
   final Args<TypeExpr> args;
   final Type staticResultType;
 
-  Call(this.selector, this.args, this.staticResultType) {
+  Call(this.selector, this.args, this.staticResultType,
+      bool isInstanceCreation) {
     // TODO(sjindel/tfa): Support inferring unchecked entry-points for dynamic
     // and direct calls as well.
     if (selector is DynamicSelector || selector is DirectSelector) {
       setUseCheckedEntry();
     }
+    if (isInstanceCreation) {
+      setInstanceCreation();
+    }
   }
 
   @override
@@ -260,12 +265,18 @@
     if (selector is! DirectSelector) {
       _observeReceiverType(argTypes[0], typeHierarchy);
     }
+    if (isInstanceCreation) {
+      callHandler
+          .addAllocatedClass((argTypes[0] as ConcreteType).cls.classNode);
+    }
     final Stopwatch timer = kPrintTimings ? (new Stopwatch()..start()) : null;
     Type result = callHandler.applyCall(
         this, selector, new Args<Type>(argTypes, names: args.names),
         isResultUsed: isResultUsed);
     summary.calleeTime += kPrintTimings ? timer.elapsedMicroseconds : 0;
-    if (isResultUsed) {
+    if (isInstanceCreation) {
+      result = argTypes[0];
+    } else if (isResultUsed) {
       if (staticResultType != null) {
         result = result.intersection(staticResultType, typeHierarchy);
       }
@@ -287,6 +298,7 @@
   static const int kReachable = (1 << 4);
   static const int kUseCheckedEntry = (1 << 5);
   static const int kReceiverMayBeInt = (1 << 6);
+  static const int kInstanceCreation = (1 << 7);
 
   Member _monomorphicTarget;
 
@@ -306,6 +318,8 @@
 
   bool get useCheckedEntry => (_flags & kUseCheckedEntry) != 0;
 
+  bool get isInstanceCreation => (_flags & kInstanceCreation) != 0;
+
   Type get resultType => _resultType;
 
   void setUseCheckedEntry() {
@@ -320,6 +334,10 @@
     _flags |= kReachable;
   }
 
+  void setInstanceCreation() {
+    _flags |= kInstanceCreation;
+  }
+
   void setPolymorphic() {
     _flags = (_flags & ~kMonomorphic) | kPolymorphic;
     _monomorphicTarget = null;
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index fac8e00..362bc5c 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -127,8 +127,13 @@
           // This pattern may appear after approximations during summary
           // normalization (so it's not enough to handle it in _makeNarrow).
           final arg = st.arg;
-          if (arg is Type && st.type == const AnyType()) {
-            return (arg is NullableType) ? arg.baseType : arg;
+          if (st.type is AnyType) {
+            if (arg is Type) {
+              return (arg is NullableType) ? arg.baseType : arg;
+            }
+            if (arg is Call && arg.isInstanceCreation) {
+              return arg;
+            }
           }
         }
 
@@ -1073,7 +1078,8 @@
     _declareVariable(decl, _typesBuilder.fromStaticType(decl.type, true));
   }
 
-  Call _makeCall(TreeNode node, Selector selector, Args<TypeExpr> args) {
+  Call _makeCall(TreeNode node, Selector selector, Args<TypeExpr> args,
+      {bool isInstanceCreation = false}) {
     Type staticResultType = null;
     Member target;
     if (selector is DirectSelector) {
@@ -1086,7 +1092,7 @@
         node is Expression) {
       staticResultType = _staticType(node);
     }
-    Call call = new Call(selector, args, staticResultType);
+    Call call = new Call(selector, args, staticResultType, isInstanceCreation);
     _summary.add(call);
     if (node != null) {
       callSites[node] = call;
@@ -1109,6 +1115,8 @@
       if (type == const AnyType()) {
         return (arg is NullableType) ? arg.baseType : arg;
       }
+    } else if (arg is Call && arg.isInstanceCreation && type is AnyType) {
+      return arg;
     }
     if (type is NullableType && type.baseType == const AnyType()) {
       return arg;
@@ -1495,12 +1503,12 @@
   @override
   TypeExpr visitConstructorInvocation(ConstructorInvocation node) {
     ConcreteType klass =
-        _entryPointsListener.addAllocatedClass(node.constructedType.classNode);
+        _typesBuilder.getTFClass(node.constructedType.classNode).concreteType;
     TypeExpr receiver =
         _translator.instantiateConcreteType(klass, node.arguments.types);
     final args = _visitArguments(receiver, node.arguments);
-    _makeCall(node, new DirectSelector(node.target), args);
-    return receiver;
+    return _makeCall(node, new DirectSelector(node.target), args,
+        isInstanceCreation: true);
   }
 
   @override
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
index bbd410a..b9d7b32 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
@@ -34,8 +34,8 @@
 %a2 = _Parameter #2 [_T (dart.core::Object)+?]
 %a3 = _Parameter #3 [_T (dart.core::Object)+?]
 %a4 = _Parameter #4 [_T (dart.core::Object)+?]
-t5 = _Call direct [#lib::B.] (_T (#lib::B))
-t6 = _Call [#lib::A.foo1] (%aa, _T (#lib::B))
+t5* = _Call direct [#lib::B.] (_T (#lib::B))
+t6 = _Call [#lib::A.foo1] (%aa, t5)
 t7 = _Narrow (%aa to _T ANY)
 t8* = _Call get [#lib::A.foo2] (t7)
 t9 = _TypeCheck (t8 against dart.core::int*) (for aa.{#lib::A.foo2} as dart.core::int*)
@@ -50,8 +50,8 @@
 %a2 = _Parameter #2 [_T (dart.core::Object)+?]
 %a3 = _Parameter #3 [_T (dart.core::Object)+?]
 %a4 = _Parameter #4 [_T (dart.core::Object)+?]
-t5 = _Call direct [#lib::B.] (_T (#lib::B))
-t6 = _Call dynamic [foo1] (%aa, _T (#lib::B))
+t5* = _Call direct [#lib::B.] (_T (#lib::B))
+t6 = _Call dynamic [foo1] (%aa, t5)
 t7 = _Narrow (%aa to _T ANY)
 t8* = _Call dynamic get [foo2] (t7)
 t9 = _Call dynamic set [foo3] (t7, t8)
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect
index 6f36339..9a4772b 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect
@@ -6,8 +6,8 @@
 %this = _Parameter #0 [_T (#lib::C)+]
 t1 = _Extract (%this[#lib::C/0]*)
 t2 = _CreateConcreteType (#lib::D @ (t1))
-t3 = _Call direct [#lib::D.] (t2)
-RESULT: t2
+t3* = _Call direct [#lib::D.] (t2)
+RESULT: t3
 ------------ C.id1 ------------
 %this = _Parameter #0 [_T (#lib::C)+]
 %x = _Parameter #1
@@ -36,14 +36,14 @@
 %this = _Parameter #0 [_T (#lib::E)+]
 t1 = _Extract (%this[#lib::E/0]*)
 t2 = _CreateConcreteType (#lib::D @ (t1))
-t3 = _Call direct [#lib::D.] (t2)
-RESULT: t2
+t3* = _Call direct [#lib::D.] (t2)
+RESULT: t3
 ------------ E.baz ------------
 %this = _Parameter #0 [_T (#lib::E)+]
 t1 = _Extract (%this[#lib::E/1]*)
 t2 = _CreateConcreteType (#lib::D @ (t1))
-t3 = _Call direct [#lib::D.] (t2)
-RESULT: t2
+t3* = _Call direct [#lib::D.] (t2)
+RESULT: t3
 ------------ X. ------------
 %this = _Parameter #0 [_T (#lib::X)+]
 t1 = _Call direct [dart.core::Object.] (%this)
@@ -88,21 +88,21 @@
 t5 = _TypeCheck (%x against t4) (for #lib::K<#lib::I<#lib::C2.T*>*>* x;)
 RESULT: t5
 ------------ main ------------
-t0 = _Call direct [#lib::C.] (_T (#lib::C<dart.core::int*>))
-t1 = _Call [#lib::C.foo] (_T (#lib::C<dart.core::int*>))
-t2 = _Call direct [#lib::E.] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t3 = _Call [#lib::E.foo] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t4 = _Call direct [#lib::E.] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t5 = _Call [#lib::E.bar] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t6 = _Call direct [#lib::E.] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t7* = _Call [#lib::E.baz] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t8 = _Call direct [#lib::C.] (_T (#lib::C<#lib::Y*>))
-t9 = _Call direct [#lib::Y.] (_T (#lib::Y))
-t10 = _Call [#lib::C.id1] (_T (#lib::C<#lib::Y*>), _T (#lib::Y))
-t11 = _Call direct [#lib::Z.] (_T (#lib::Z))
-t12 = _Call [#lib::C.id2] (_T (#lib::C<#lib::Y*>), _T (#lib::Z))
-t13 = _Call direct [#lib::C2.] (_T (#lib::C2<dart.core::num*>))
-t14 = _Call [#lib::C2.id3] (_T (#lib::C2<dart.core::num*>), _T (dart.core::_Double, 3.0))
-t15 = _Call direct [#lib::K.] (_T (#lib::K<#lib::J*>))
-t16 = _Call [#lib::C2.id4] (_T (#lib::C2<dart.core::num*>), _T (#lib::K<#lib::J*>))
+t0* = _Call direct [#lib::C.] (_T (#lib::C<dart.core::int*>))
+t1 = _Call [#lib::C.foo] (t0)
+t2* = _Call direct [#lib::E.] (_T (#lib::E<dart.core::int*, dart.core::String*>))
+t3 = _Call [#lib::E.foo] (t2)
+t4* = _Call direct [#lib::E.] (_T (#lib::E<dart.core::int*, dart.core::String*>))
+t5 = _Call [#lib::E.bar] (t4)
+t6* = _Call direct [#lib::E.] (_T (#lib::E<dart.core::int*, dart.core::String*>))
+t7* = _Call [#lib::E.baz] (t6)
+t8* = _Call direct [#lib::C.] (_T (#lib::C<#lib::Y*>))
+t9* = _Call direct [#lib::Y.] (_T (#lib::Y))
+t10 = _Call [#lib::C.id1] (t8, t9)
+t11* = _Call direct [#lib::Z.] (_T (#lib::Z))
+t12 = _Call [#lib::C.id2] (t8, t11)
+t13* = _Call direct [#lib::C2.] (_T (#lib::C2<dart.core::num*>))
+t14 = _Call [#lib::C2.id3] (t13, _T (dart.core::_Double, 3.0))
+t15* = _Call direct [#lib::K.] (_T (#lib::K<#lib::J*>))
+t16 = _Call [#lib::C2.id4] (t13, t15)
 RESULT: t7
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect
index 0eea29d..ad64881 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect
@@ -6,8 +6,8 @@
 %K = _Parameter #0
 %V = _Parameter #1
 t2 = _CreateConcreteType (#lib::_NotRealHashMap @ (%K, %V))
-t3 = _Call direct [#lib::_NotRealHashMap.] (t2)
-RESULT: t2
+t3* = _Call direct [#lib::_NotRealHashMap.] (t2)
+RESULT: t3
 ------------ _NotRealHashMap. ------------
 %this = _Parameter #0 [_T (#lib::_NotRealHashMap)+]
 t1 = _Call direct [dart.core::Object.] (%this)
@@ -37,8 +37,8 @@
 t1* = _Call direct [#lib::MockHashMap.] (#lib::Element*, dart.core::Object*)
 RESULT: t1
 ------------ main ------------
-t0 = _Call direct [#lib::InheritedElement.] (_T (#lib::InheritedElement))
-t1 = _Call [#lib::InheritedElement.setDependencies] (_T (#lib::InheritedElement), _T (#lib::InheritedElement), _T (dart.core::_Smi, 0))
-t2 = _Call direct [#lib::Element.] (_T (#lib::Element))
-t3 = _Call [#lib::InheritedElement.setDependencies] (_T (#lib::InheritedElement), _T (#lib::Element), _T {}?)
+t0* = _Call direct [#lib::InheritedElement.] (_T (#lib::InheritedElement))
+t1 = _Call [#lib::InheritedElement.setDependencies] (t0, t0, _T (dart.core::_Smi, 0))
+t2* = _Call direct [#lib::Element.] (_T (#lib::Element))
+t3 = _Call [#lib::InheritedElement.setDependencies] (t0, t2, _T {}?)
 RESULT: _T {}?
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
index d0227dd..e434ee3 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
@@ -47,53 +47,53 @@
 ------------ sequence ------------
 t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
 t1 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t2 = _Call direct [#lib::C3.] (_T (#lib::C3))
-RESULT: _T (#lib::C3)
+t2* = _Call direct [#lib::C3.] (_T (#lib::C3))
+RESULT: t2
 ------------ if1 ------------
 %cond = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t2 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t3 = _Call direct [#lib::foo] (_T (#lib::C2))
-x_0 = _Join [dynamic] (_T (#lib::C2), _T (#lib::C1))
+t1* = _Call direct [#lib::C1.] (_T (#lib::C1))
+t2* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t3 = _Call direct [#lib::foo] (t2)
+x_0 = _Join [dynamic] (t2, t1)
 RESULT: x_0
 ------------ if2 ------------
 %cond1 = _Parameter #0 [_T (dart.core::bool)+?]
 %cond2 = _Parameter #1 [_T (dart.core::bool)+?]
-t2 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t3 = _Call direct [#lib::foo] (_T (#lib::C1))
-t4 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t5 = _Call direct [#lib::bar] (_T (#lib::C2))
-x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2))
+t2* = _Call direct [#lib::C1.] (_T (#lib::C1))
+t3 = _Call direct [#lib::foo] (t2)
+t4* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t5 = _Call direct [#lib::bar] (t4)
+x_0 = _Join [dynamic] (t2, t4)
 RESULT: x_0
 ------------ if3 ------------
 %cond1 = _Parameter #0 [_T (dart.core::bool)+?]
 %cond2 = _Parameter #1 [_T (dart.core::bool)+?]
 t2 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t3 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t4* = _Call direct [#lib::foo] (_T (#lib::C2))
+t3* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t4* = _Call direct [#lib::foo] (t3)
 t5 = _TypeCheck (t4 against dart.core::bool*) (for #lib::foo(x = new #lib::C2()) as dart.core::bool*)
-t6 = _Call direct [#lib::C3.] (_T (#lib::C3))
-t7* = _Call direct [#lib::foo] (_T (#lib::C3))
+t6* = _Call direct [#lib::C3.] (_T (#lib::C3))
+t7* = _Call direct [#lib::foo] (t6)
 t8 = _TypeCheck (t7 against dart.core::bool*) (for #lib::foo(x = new #lib::C3()) as dart.core::bool*)
-x_0 = _Join [dynamic] (_T (#lib::C2), _T (#lib::C3))
+x_0 = _Join [dynamic] (t3, t6)
 t10 = _Call direct [#lib::bar] (x_0)
 RESULT: x_0
 ------------ if4 ------------
 t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t1 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t2* = _Call direct [#lib::foo] (_T (#lib::C2))
+t1* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t2* = _Call direct [#lib::foo] (t1)
 t3 = _TypeCheck (t2 against dart.core::bool*) (for #lib::foo(x = new #lib::C2()) as dart.core::bool*)
-t4 = _Call direct [#lib::C3.] (_T (#lib::C3))
-t5* = _Call direct [#lib::foo] (_T (#lib::C3))
+t4* = _Call direct [#lib::C3.] (_T (#lib::C3))
+t5* = _Call direct [#lib::foo] (t4)
 t6 = _TypeCheck (t5 against dart.core::bool*) (for #lib::foo(x = new #lib::C3()) as dart.core::bool*)
-t7 = _Call direct [#lib::bar] (_T (#lib::C3))
-x_0 = _Join [dynamic] (_T (#lib::C2), _T (#lib::C3))
+t7 = _Call direct [#lib::bar] (t4)
+x_0 = _Join [dynamic] (t1, t4)
 RESULT: x_0
 ------------ if5 ------------
 %cond = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1* = _Call direct [#lib::C1.] (_T (#lib::C1))
 t2 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t3 = _Call direct [#lib::foo] (_T (#lib::C1))
+t3 = _Call direct [#lib::foo] (t1)
 RESULT: _T {}?
 ------------ if6a ------------
 %x = _Parameter #0 [_T (dart.core::bool)+?]
@@ -136,14 +136,14 @@
 %cond1 = _Parameter #0 [_T (dart.core::bool)+?]
 %cond2 = _Parameter #1 [_T (dart.core::bool)+?]
 t2 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t3 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t4* = _Call direct [#lib::foo] (_T (#lib::C2))
+t3* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t4* = _Call direct [#lib::foo] (t3)
 t5 = _TypeCheck (t4 against dart.core::bool*) (for #lib::foo(x = new #lib::C2()) as dart.core::bool*)
-t6 = _Call direct [#lib::C3.] (_T (#lib::C3))
-t7 = _Call direct [#lib::C4.] (_T (#lib::C4))
-x_0 = _Join [dynamic] (_T (#lib::C3), _T (#lib::C4))
+t6* = _Call direct [#lib::C3.] (_T (#lib::C3))
+t7* = _Call direct [#lib::C4.] (_T (#lib::C4))
+x_0 = _Join [dynamic] (t6, t7)
 t9 = _Call direct [#lib::foo] (x_0)
-t10 = _Join [dart.core::Object*] (_T (#lib::C3), _T (#lib::C4))
+t10 = _Join [dart.core::Object*] (t6, t7)
 t11 = _Narrow (t10 to _T (dart.core::Object)+?)
 t12 = _Call direct [#lib::bar] (t11)
 RESULT: _T {}?
@@ -151,125 +151,125 @@
 %cond1 = _Parameter #0 [_T (dart.core::bool)+?]
 %cond2 = _Parameter #1 [_T (dart.core::bool)+?]
 t2 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t3 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t4* = _Call direct [#lib::foo] (_T (#lib::C2))
+t3* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t4* = _Call direct [#lib::foo] (t3)
 t5 = _TypeCheck (t4 against dart.core::bool*) (for #lib::foo(x = new #lib::C2()) as dart.core::bool*)
-t6 = _Call direct [#lib::C3.] (_T (#lib::C3))
-t7 = _Call direct [#lib::C4.] (_T (#lib::C4))
-t8* = _Call direct [dart.core::_GrowableList._literal2] (#lib::C4*, _T (#lib::C4), _T {})
+t6* = _Call direct [#lib::C3.] (_T (#lib::C3))
+t7* = _Call direct [#lib::C4.] (_T (#lib::C4))
+t8* = _Call direct [dart.core::_GrowableList._literal2] (#lib::C4*, t7, _T {})
 t9* = _Call direct [#lib::foo] (t8)
-t10 = _Call direct [#lib::foo] (_T (#lib::C3))
-t11 = _Join [dynamic] (_T (#lib::C3), t9)
+t10 = _Call direct [#lib::foo] (t6)
+t11 = _Join [dynamic] (t6, t9)
 t12 = _Call direct [#lib::bar] (t11)
 RESULT: _T {}?
 ------------ loop1 ------------
-t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
-x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2))
-t2* = _Call direct [#lib::foo] (x_0)
-t3 = _TypeCheck (t2 against dart.core::bool*) (for #lib::foo(x) as dart.core::bool*)
-t4 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t0* = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1* = _Call direct [#lib::C2.] (_T (#lib::C2))
+x_0 = _Join [dynamic] (t0, t1)
+t3* = _Call direct [#lib::foo] (x_0)
+t4 = _TypeCheck (t3 against dart.core::bool*) (for #lib::foo(x) as dart.core::bool*)
 t5 = _Call direct [#lib::bar] (x_0)
 RESULT: x_0
 ------------ loop2 ------------
-t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
-x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C3))
-t2 = _Call direct [#lib::foo] (x_0)
-t3 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t4 = _Call direct [#lib::bar] (_T (#lib::C2))
-t5 = _Call direct [#lib::C3.] (_T (#lib::C3))
-t6* = _Call direct [#lib::bar] (_T (#lib::C3))
+t0* = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1* = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_0 = _Join [dynamic] (t0, t1)
+t3 = _Call direct [#lib::foo] (x_0)
+t4* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t5 = _Call direct [#lib::bar] (t4)
+t6* = _Call direct [#lib::bar] (t1)
 t7 = _TypeCheck (t6 against dart.core::bool*) (for #lib::bar(x = new #lib::C3()) as dart.core::bool*)
-RESULT: _T (#lib::C3)
+RESULT: t1
 ------------ loop3 ------------
 t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t1 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t2* = _Call direct [#lib::foo] (_T (#lib::C2))
+t1* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t2* = _Call direct [#lib::foo] (t1)
 t3 = _TypeCheck (t2 against dart.core::bool*) (for #lib::foo(x = new #lib::C2()) as dart.core::bool*)
 t4 = _Call direct [#lib::C3.] (_T (#lib::C3))
-t5 = _Call direct [#lib::bar] (_T (#lib::C2))
-RESULT: _T (#lib::C2)
+t5 = _Call direct [#lib::bar] (t1)
+RESULT: t1
 ------------ loop4 ------------
 t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t1 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t2* = _Call direct [#lib::foo] (_T (#lib::C2))
+t1* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t2* = _Call direct [#lib::foo] (t1)
 t3* = _Call direct [dart.core::_GrowableList._literal1] (dynamic?, t2)
 t4* = _Call get [dart.core::Iterable.iterator] (t3)
 t5* = _Call [dart.core::Iterator.moveNext] (t4)
 t6 = _Narrow (t4 to _T ANY)
 t7 = _Call get [dart.core::Iterator.current] (t6)
-x_0 = _Join [dynamic] (_T (#lib::C2), _T (#lib::C3))
-t9 = _Call direct [#lib::foo] (x_0)
-t10 = _Call direct [#lib::C3.] (_T (#lib::C3))
+t8* = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_0 = _Join [dynamic] (t1, t8)
+t10 = _Call direct [#lib::foo] (x_0)
 RESULT: x_0
 ------------ loop5 ------------
-t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
-x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C3))
-t2* = _Call direct [#lib::foo] (x_0)
-t3 = _TypeCheck (t2 against dart.core::bool*) (for #lib::foo(x) as dart.core::bool*)
-t4 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t5* = _Call direct [#lib::bar] (_T (#lib::C2))
-t6 = _TypeCheck (t5 against dart.core::bool*) (for #lib::bar(x) as dart.core::bool*)
-t7 = _Call direct [#lib::C3.] (_T (#lib::C3))
-x_1 = _Join [dynamic] (x_0, _T (#lib::C2))
-RESULT: x_1
------------- loop6 ------------
-t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
-x_1 = _Join [dynamic] (_T (#lib::C3), _T (#lib::C2))
-x_0 = _Join [dynamic] (_T (#lib::C1), x_1)
+t0* = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1* = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_0 = _Join [dynamic] (t0, t1)
 t3* = _Call direct [#lib::foo] (x_0)
 t4 = _TypeCheck (t3 against dart.core::bool*) (for #lib::foo(x) as dart.core::bool*)
-t5 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t6* = _Call direct [#lib::bar] (_T (#lib::C2))
+t5* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t6* = _Call direct [#lib::bar] (t5)
 t7 = _TypeCheck (t6 against dart.core::bool*) (for #lib::bar(x) as dart.core::bool*)
-t8 = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_1 = _Join [dynamic] (x_0, t5)
+RESULT: x_1
+------------ loop6 ------------
+t0* = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1* = _Call direct [#lib::C3.] (_T (#lib::C3))
+t2* = _Call direct [#lib::C2.] (_T (#lib::C2))
+x_1 = _Join [dynamic] (t1, t2)
+x_0 = _Join [dynamic] (t0, x_1)
+t5* = _Call direct [#lib::foo] (x_0)
+t6 = _TypeCheck (t5 against dart.core::bool*) (for #lib::foo(x) as dart.core::bool*)
+t7* = _Call direct [#lib::bar] (t2)
+t8 = _TypeCheck (t7 against dart.core::bool*) (for #lib::bar(x) as dart.core::bool*)
 RESULT: x_0
 ------------ try1 ------------
-t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t1 = _Call direct [#lib::C2.] (_T (#lib::C2))
-x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2), _T (#lib::C3))
-t3 = _Call direct [#lib::foo] (x_0)
-t4 = _Call direct [#lib::C3.] (_T (#lib::C3))
+t0* = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t2* = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_0 = _Join [dynamic] (t0, t1, t2)
+t4 = _Call direct [#lib::foo] (x_0)
 t5 = _Call direct [#lib::bar] (x_0)
-t6 = _Call direct [#lib::C4.] (_T (#lib::C4))
-RESULT: _T (#lib::C4)
+t6* = _Call direct [#lib::C4.] (_T (#lib::C4))
+RESULT: t6
 ------------ closure1 ------------
-t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
-x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2))
-t2 = _Call direct [#lib::foo] (x_0)
-t3 = _Call direct [#lib::bar] (x_0)
-t4 = _Call direct [#lib::foo] (_T ANY?)
-t5 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t0* = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1* = _Call direct [#lib::C2.] (_T (#lib::C2))
+x_0 = _Join [dynamic] (t0, t1)
+t3 = _Call direct [#lib::foo] (x_0)
+t4 = _Call direct [#lib::bar] (x_0)
+t5 = _Call direct [#lib::foo] (_T ANY?)
 RESULT: _T {}?
 ------------ closure2 ------------
-t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
-x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2))
-t2 = _Call direct [#lib::foo] (x_0)
-t3 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t0* = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1* = _Call direct [#lib::C2.] (_T (#lib::C2))
+x_0 = _Join [dynamic] (t0, t1)
+t3 = _Call direct [#lib::foo] (x_0)
 t4 = _Call direct [#lib::foo] (_T ANY?)
 RESULT: x_0
 ------------ switch1 ------------
 %selector = _Parameter #0 [_T (dart.core::int)+?]
-t1 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t2 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t3 = _Call direct [#lib::C3.] (_T (#lib::C3))
-x_2 = _Join [dynamic] (_T (#lib::C3), _T (#lib::C1))
-x_3 = _Join [dynamic] (x_2, _T (#lib::C2))
+t1* = _Call direct [#lib::C1.] (_T (#lib::C1))
+t2* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t3* = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_2 = _Join [dynamic] (t3, t1)
+x_3 = _Join [dynamic] (x_2, t2)
 RESULT: x_3
 ------------ switch2 ------------
 %selector = _Parameter #0 [_T (dart.core::int)+?]
 t1 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t2 = _Call direct [#lib::C2.] (_T (#lib::C2))
-t3 = _Call direct [#lib::C3.] (_T (#lib::C3))
-x_2 = _Join [dynamic] (_T (#lib::C3), _T (#lib::C2))
+t2* = _Call direct [#lib::C2.] (_T (#lib::C2))
+t3* = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_2 = _Join [dynamic] (t3, t2)
 RESULT: x_2
 ------------ switch3 ------------
 %selector = _Parameter #0 [_T (dart.core::int)+?]
-t1 = _Call direct [#lib::C1.] (_T (#lib::C1))
-t2 = _Call direct [#lib::C2.] (_T (#lib::C2))
-x_1 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2))
+t1* = _Call direct [#lib::C1.] (_T (#lib::C1))
+t2* = _Call direct [#lib::C2.] (_T (#lib::C2))
+x_1 = _Join [dynamic] (t1, t2)
 t4 = _Call direct [#lib::foo] (x_1)
-t5 = _Call direct [#lib::C3.] (_T (#lib::C3))
-x_2 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C3))
+t5* = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_2 = _Join [dynamic] (t1, t5)
 RESULT: x_2
 ------------ cast1 ------------
 %x = _Parameter #0 [_T ANY?]
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
index b584c86..8b3a909 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
@@ -15,16 +15,16 @@
 
 RESULT: _T {}?
 ------------ return1 ------------
-t0 = _Call direct [#lib::T.] (_T (#lib::T))
-RESULT: _T (#lib::T)
+t0* = _Call direct [#lib::T.] (_T (#lib::T))
+RESULT: t0
 ------------ return2 ------------
 %i = _Parameter #0 [_T (dart.core::int)+?]
 t1* = _Call [dart.core::num.-] (%i, _T (dart.core::_Smi, 1))
 t2* = _Call direct [#lib::return2] (t1)
 RESULT: t2
 ------------ return3 ------------
-t0 = _Call direct [#lib::T.] (_T (#lib::T))
-RESULT: _T (#lib::T)
+t0* = _Call direct [#lib::T.] (_T (#lib::T))
+RESULT: t0
 ------------ return4 ------------
 
 RESULT: _T {}?
@@ -33,16 +33,16 @@
 RESULT: _T {}?
 ------------ expr2 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [#lib::T.] (_T (#lib::T))
+t1* = _Call direct [#lib::T.] (_T (#lib::T))
 t2 = _Call direct [#lib::T.] (_T (#lib::T))
-%result = _Join [dynamic] (_T (#lib::T), _T {}?)
+%result = _Join [dynamic] (t1, _T {}?)
 RESULT: %result
 ------------ expr3 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
 %x = _Parameter #1 [_T (dart.core::Object)+?]
-t2 = _Call direct [#lib::T.] (_T (#lib::T))
+t2* = _Call direct [#lib::T.] (_T (#lib::T))
 t3 = _Call [dart.core::Object.toString] (%x)
-%result = _Join [dynamic] (_T (#lib::T), _T {}?)
+%result = _Join [dynamic] (t2, _T {}?)
 RESULT: %result
 ------------ throw1 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
@@ -51,8 +51,8 @@
 ------------ throw2 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
 %x = _Parameter #1 [_T (dart.core::Object)+?]
-t2 = _Call direct [#lib::T.] (_T (#lib::T))
-RESULT: _T (#lib::T)
+t2* = _Call direct [#lib::T.] (_T (#lib::T))
+RESULT: t2
 ------------ loop1 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
 %x = _Parameter #1 [_T (dart.core::Object)+?]
@@ -60,29 +60,29 @@
 ------------ loop2 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
 %x = _Parameter #1 [_T (dart.core::Object)+?]
-t2 = _Call direct [#lib::T.] (_T (#lib::T))
-%result = _Join [dynamic] (_T (#lib::T), _T {}?)
+t2* = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (t2, _T {}?)
 RESULT: %result
 ------------ loop3 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
 %x = _Parameter #1 [_T (dart.core::Object)+?]
-t2 = _Call direct [#lib::T.] (_T (#lib::T))
-%result = _Join [dynamic] (_T (#lib::T), _T {}?)
+t2* = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (t2, _T {}?)
 RESULT: %result
 ------------ switch_ ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
 %i = _Parameter #1 [_T (dart.core::int)+?]
-t2 = _Call direct [#lib::T.] (_T (#lib::T))
-%result = _Join [dynamic] (_T (#lib::T), _T {}?)
+t2* = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (t2, _T {}?)
 RESULT: %result
 ------------ if1 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [#lib::T.] (_T (#lib::T))
-RESULT: _T (#lib::T)
+t1* = _Call direct [#lib::T.] (_T (#lib::T))
+RESULT: t1
 ------------ if2 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [#lib::T.] (_T (#lib::T))
-%result = _Join [dynamic] (_T (#lib::T), _T {}?)
+t1* = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (t1, _T {}?)
 RESULT: %result
 ------------ if3 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
@@ -98,36 +98,36 @@
 RESULT: %result
 ------------ label1 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [#lib::T.] (_T (#lib::T))
-%result = _Join [dynamic] (_T (#lib::T), _T {}?)
+t1* = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (t1, _T {}?)
 RESULT: %result
 ------------ try1 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [#lib::T.] (_T (#lib::T))
-%result = _Join [dynamic] (_T (#lib::T), _T {}?)
+t1* = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (t1, _T {}?)
 RESULT: %result
 ------------ try2 ------------
-t0 = _Call direct [#lib::T.] (_T (#lib::T))
-%result = _Join [dynamic] (_T (#lib::T), _T {}?)
+t0* = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (t0, _T {}?)
 RESULT: %result
 ------------ try3 ------------
-t0 = _Call direct [#lib::T.] (_T (#lib::T))
-RESULT: _T (#lib::T)
+t0* = _Call direct [#lib::T.] (_T (#lib::T))
+RESULT: t0
 ------------ try4 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [#lib::T.] (_T (#lib::T))
-%result = _Join [dynamic] (_T (#lib::T), _T {}?)
+t1* = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (t1, _T {}?)
 RESULT: %result
 ------------ try5 ------------
-t0 = _Call direct [#lib::T.] (_T (#lib::T))
-RESULT: _T (#lib::T)
+t0* = _Call direct [#lib::T.] (_T (#lib::T))
+RESULT: t0
 ------------ try6 ------------
-t0 = _Call direct [#lib::T.] (_T (#lib::T))
-RESULT: _T (#lib::T)
+t0* = _Call direct [#lib::T.] (_T (#lib::T))
+RESULT: t0
 ------------ try7 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [#lib::T.] (_T (#lib::T))
-RESULT: _T (#lib::T)
+t1* = _Call direct [#lib::T.] (_T (#lib::T))
+RESULT: t1
 ------------ main ------------
 
 RESULT: _T {}?
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
index d46d957..4bba0a1 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
@@ -10,12 +10,12 @@
 %a1 = _Parameter #0 [_T (dart.core::Object)+?]
 %a2 = _Parameter #1 [_T (dart.core::Object)+?]
 t2* = _Call direct get [#lib::someStatic] ()
-t3 = _Call direct [#lib::A.] (_T (#lib::A))
-a1_0 = _Join [dart.core::Object*] (_T (#lib::A), %a1)
+t3* = _Call direct [#lib::A.] (_T (#lib::A))
+a1_0 = _Join [dart.core::Object*] (t3, %a1)
 t5 = _Call direct [#lib::bar] (a1_0, _T (dart.core::_Smi, 42))
-t6 = _Call direct [#lib::B.] (_T (#lib::B))
-t7* = _Call [dart.core::Object.==] (_T (#lib::B), %a2)
-t8 = _Join [dart.core::Object*] (_T (#lib::B), %a2)
+t6* = _Call direct [#lib::B.] (_T (#lib::B))
+t7* = _Call [dart.core::Object.==] (t6, %a2)
+t8 = _Join [dart.core::Object*] (t6, %a2)
 t9 = _Narrow (t8 to _T (dart.core::Object)+?)
 RESULT: t9
 ------------ bar ------------
diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
index f04ffbb..ad83f7b 100644
--- a/sdk/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk/lib/_internal/vm/bin/socket_patch.dart
@@ -1489,7 +1489,8 @@
       InternetAddress addr, NetworkInterface? interface) {
     // On Mac OS using the interface index for joining IPv4 multicast groups
     // is not supported. Here the IP address of the interface is needed.
-    if (Platform.isMacOS && addr.type == InternetAddressType.IPv4) {
+    if ((Platform.isMacOS || Platform.isIOS) &&
+        addr.type == InternetAddressType.IPv4) {
       if (interface != null) {
         for (int i = 0; i < interface.addresses.length; i++) {
           if (interface.addresses[i].type == InternetAddressType.IPv4) {
diff --git a/tools/VERSION b/tools/VERSION
index f7ef7a9..ce25a45 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 310
+PRERELEASE 311
 PRERELEASE_PATCH 0
\ No newline at end of file