[mcs] Codegen for optimized new with valuetype load and awaited arguments. Fixes...
[mono.git] / mcs / mcs / expression.cs
index c7747f014fdee5da31e0b772c45dbdaa148c769c..9042dcdabad8e5405cbbbc086953ade32d7dfc81 100644 (file)
@@ -718,8 +718,11 @@ namespace Mono.CSharp
 
                Expression ResolveAddressOf (ResolveContext ec)
                {
-                       if (!ec.IsUnsafe)
+                       if (ec.CurrentIterator != null) {
+                               UnsafeInsideIteratorError (ec, loc);
+                       } else if (!ec.IsUnsafe) {
                                UnsafeError (ec, loc);
+                       }
 
                        Expr = Expr.DoResolveLValue (ec, EmptyExpression.UnaryAddress);
                        if (Expr == null || Expr.eclass != ExprClass.Variable) {
@@ -737,7 +740,7 @@ namespace Mono.CSharp
                                is_fixed = vr.IsFixed;
                                vr.SetHasAddressTaken ();
 
-                               if (vr.IsHoisted) {
+                               if (vr.IsHoisted && ec.CurrentIterator == null) {
                                        AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, vr, loc);
                                }
                        } else {
@@ -984,8 +987,11 @@ namespace Mono.CSharp
                        if (expr == null)
                                return null;
 
-                       if (!ec.IsUnsafe)
+                       if (ec.CurrentIterator != null) {
+                               UnsafeInsideIteratorError (ec, loc);
+                       } else if (!ec.IsUnsafe) {
                                UnsafeError (ec, loc);
+                       }
 
                        var pc = expr.Type as PointerContainer;
 
@@ -2453,8 +2459,12 @@ namespace Mono.CSharp
                                return null;
                        }
 
-                       if (type.IsPointer && !ec.IsUnsafe) {
-                               UnsafeError (ec, loc);
+                       if (type.IsPointer) {
+                               if (ec.CurrentIterator != null) {
+                                       UnsafeInsideIteratorError (ec, loc);
+                               } else if (!ec.IsUnsafe) {
+                                       UnsafeError (ec, loc);
+                               }
                        }
 
                        eclass = ExprClass.Value;
@@ -7560,14 +7570,21 @@ namespace Mono.CSharp
                        bool is_value_type = type.IsStructOrEnum;
                        VariableReference vr = target as VariableReference;
 
+                       bool prepare_await = ec.HasSet (BuilderContext.Options.AsyncBody) && arguments?.ContainsEmitWithAwait () == true;
+
                        if (target != null && is_value_type && (vr != null || method == null)) {
+                               if (prepare_await) {
+                                       arguments = arguments.Emit (ec, false, true);
+                                       prepare_await = false;
+                               }
+                               
                                target.AddressOf (ec, AddressOp.Store);
                        } else if (vr != null && vr.IsRef) {
                                vr.EmitLoad (ec);
                        }
 
                        if (arguments != null) {
-                               if (ec.HasSet (BuilderContext.Options.AsyncBody) && (arguments.Count > (this is NewInitialize ? 0 : 1)) && arguments.ContainsEmitWithAwait ())
+                               if (prepare_await)
                                        arguments = arguments.Emit (ec, false, true);
 
                                arguments.Emit (ec);
@@ -10485,8 +10502,12 @@ namespace Mono.CSharp
                        }
 
                        type = ac.Element;
-                       if (type.IsPointer && !ec.IsUnsafe) {
-                               UnsafeError (ec, ea.Location);
+                       if (type.IsPointer) {
+                               if (ec.CurrentIterator != null) {
+                                       UnsafeInsideIteratorError (ec, ea.Location);
+                               } else if (!ec.IsUnsafe) {
+                                       UnsafeError (ec, ea.Location);
+                               }
                        }
 
                        if (conditional_access_receiver)
@@ -11404,7 +11425,10 @@ namespace Mono.CSharp
                                if (!(ec.CurrentMemberDefinition is Field) && !TypeManager.VerifyUnmanaged (ec.Module, type, loc))
                                        return null;
 
-                               if (!ec.IsUnsafe) {
+                               var rc = ec as ResolveContext;
+                               if (rc?.CurrentIterator != null) {
+                                       UnsafeInsideIteratorError (ec.Module.Compiler.Report, loc);
+                               } else if (!ec.IsUnsafe) {
                                        UnsafeError (ec.Module.Compiler.Report, loc);
                                }