Merge branch 'master' into msbuilddll2
[mono.git] / mcs / mcs / ecore.cs
index 113b95ff0a6e982299a2ca5c9c5bf7718b8b918d..ec0d7a2c60670ce1f4f3caea3dafab0ad30461a8 100644 (file)
@@ -315,7 +315,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, MemberSpec member, int arity, Location loc)
+               public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, MemberSpec member, Location loc)
                {
                        // Better message for possible generic expressions
                        if (member != null && (member.Kind & MemberKind.GenericMask) != 0) {
@@ -339,7 +339,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, string exprType, string name, Location loc)
+               public static void Error_TypeArgumentsCannotBeUsed (IMemberContext context, string exprType, string name, Location loc)
                {
                        context.Module.Compiler.Report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
                                exprType, name);
@@ -373,6 +373,11 @@ namespace Mono.CSharp {
                        rc.Report.Error (242, loc, "The operation in question is undefined on void pointers");
                }
 
+               public static void Warning_UnreachableExpression (ResolveContext rc, Location loc)
+               {
+                       rc.Report.Warning (429, 4, loc, "Unreachable expression code detected");
+               }
+
                public ResolveFlags ExprClassToResolveFlags {
                        get {
                                switch (eclass) {
@@ -435,8 +440,14 @@ namespace Mono.CSharp {
                /// </remarks>
                public Expression Resolve (ResolveContext ec, ResolveFlags flags)
                {
-                       if (eclass != ExprClass.Unresolved)
+                       if (eclass != ExprClass.Unresolved) {
+                               if ((flags & ExprClassToResolveFlags) == 0) {
+                                       Error_UnexpectedKind (ec, flags, loc);
+                                       return null;
+                               }
+
                                return this;
+                       }
                        
                        Expression e;
                        try {
@@ -455,7 +466,8 @@ namespace Mono.CSharp {
 
                                return e;
                        } catch (Exception ex) {
-                               if (loc.IsNull || ec.Module.Compiler.Settings.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled || ex is FatalException)
+                               if (loc.IsNull || ec.Module.Compiler.Settings.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled || ex is FatalException ||
+                                       ec.Report.Printer is NullReportPrinter)
                                        throw;
 
                                ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message);
@@ -511,6 +523,23 @@ namespace Mono.CSharp {
                        return e;
                }
 
+               public Constant ResolveLabelConstant (ResolveContext rc)
+               {
+                       var expr = Resolve (rc);
+                       if (expr == null)
+                               return null;
+
+                       Constant c = expr as Constant;
+                       if (c == null) {
+                               if (expr.type != InternalType.ErrorType)
+                                       rc.Report.Error (150, expr.StartLocation, "A constant value is expected");
+
+                               return null;
+                       }
+
+                       return c;
+               }
+
                public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        rc.Module.Compiler.Report.Error (182, loc,
@@ -683,13 +712,20 @@ namespace Mono.CSharp {
                {
                        var ctors = MemberCache.FindMembers (type, Constructor.ConstructorName, true);
                        if (ctors == null) {
-                               rc.Report.SymbolRelatedToPreviousError (type);
-                               if (type.IsStruct) {
+                               switch (type.Kind) {
+                               case MemberKind.Struct:
+                                       rc.Report.SymbolRelatedToPreviousError (type);
                                        // Report meaningful error for struct as they always have default ctor in C# context
                                        OverloadResolver.Error_ConstructorMismatch (rc, type, args == null ? 0 : args.Count, loc);
-                               } else {
+                                       break;
+                               case MemberKind.MissingType:
+                               case MemberKind.InternalCompilerType:
+                                       break;
+                               default:
+                                       rc.Report.SymbolRelatedToPreviousError (type);
                                        rc.Report.Error (143, loc, "The class `{0}' has no constructors defined",
                                                type.GetSignatureForError ());
+                                       break;
                                }
 
                                return null;
@@ -761,8 +797,18 @@ namespace Mono.CSharp {
                                        }
 
                                        if ((restrictions & MemberLookupRestrictions.InvocableOnly) != 0) {
-                                               if (member is MethodSpec)
+                                               if (member is MethodSpec) {
+                                                       //
+                                                       // Interface members that are hidden by class members are removed from the set. This
+                                                       // step only has an effect if T is a type parameter and T has both an effective base 
+                                                       // class other than object and a non-empty effective interface set
+                                                       //
+                                                       var tps = queried_type as TypeParameterSpec;
+                                                       if (tps != null && tps.HasTypeConstraint)
+                                                               members = RemoveHiddenTypeParameterMethods (members);
+
                                                        return new MethodGroupExpr (members, queried_type, loc);
+                                               }
 
                                                if (!Invocation.IsMemberInvocable (member))
                                                        continue;
@@ -817,6 +863,54 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               static IList<MemberSpec> RemoveHiddenTypeParameterMethods (IList<MemberSpec> members)
+               {
+                       if (members.Count < 2)
+                               return members;
+
+                       //
+                       // If M is a method, then all non-method members declared in an interface declaration
+                       // are removed from the set, and all methods with the same signature as M declared in
+                       // an interface declaration are removed from the set
+                       //
+
+                       bool copied = false;
+                       for (int i = 0; i < members.Count; ++i) {
+                               var method = members[i] as MethodSpec;
+                               if (method == null) {
+                                       if (!copied) {
+                                               copied = true;
+                                               members = new List<MemberSpec> (members);
+                                       } 
+                                       
+                                       members.RemoveAt (i--);
+                                       continue;
+                               }
+
+                               if (!method.DeclaringType.IsInterface)
+                                       continue;
+
+                               for (int ii = 0; ii < members.Count; ++ii) {
+                                       var candidate = members[ii] as MethodSpec;
+                                       if (candidate == null || !candidate.DeclaringType.IsClass)
+                                               continue;
+
+                                       if (!TypeSpecComparer.Override.IsEqual (candidate.Parameters, method.Parameters))
+                                               continue;
+
+                                       if (!copied) {
+                                               copied = true;
+                                               members = new List<MemberSpec> (members);
+                                       }
+
+                                       members.RemoveAt (i--);
+                                       break;
+                               }
+                       }
+
+                       return members;
+               }
+
                protected virtual void Error_NegativeArrayIndex (ResolveContext ec, Location loc)
                {
                        throw new NotImplementedException ();
@@ -836,6 +930,10 @@ namespace Mono.CSharp {
                        ec.Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation");
                }
 
+               public virtual void FlowAnalysis (FlowAnalysisContext fc)
+               {
+               }
+
                /// <summary>
                ///   Returns an expression that can be used to invoke operator true
                ///   on the expression if it exists.
@@ -907,7 +1005,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Reports that we were expecting `expr' to be of class `expected'
                /// </summary>
-               public void Error_UnexpectedKind (IMemberContext ctx, Expression memberExpr, string expected, string was, Location loc)
+               public static void Error_UnexpectedKind (IMemberContext ctx, Expression memberExpr, string expected, string was, Location loc)
                {
                        var name = memberExpr.GetSignatureForError ();
 
@@ -1088,6 +1186,10 @@ namespace Mono.CSharp {
        /// </summary>
        public abstract class ExpressionStatement : Expression
        {
+               public virtual void MarkReachable (Reachability rc)
+               {
+               }
+
                public ExpressionStatement ResolveStatement (BlockContext ec)
                {
                        Expression e = Resolve (ec);
@@ -1095,7 +1197,7 @@ namespace Mono.CSharp {
                                return null;
 
                        ExpressionStatement es = e as ExpressionStatement;
-                       if (es == null)
+                       if (es == null || e is AnonymousMethodBody)
                                Error_InvalidExpressionStatement (ec);
 
                        //
@@ -1223,6 +1325,11 @@ namespace Mono.CSharp {
                        child.Emit (ec);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       child.FlowAnalysis (fc);
+               }
+
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
 #if STATIC
@@ -1253,8 +1360,20 @@ namespace Mono.CSharp {
                public static Expression Create (Expression child, TypeSpec type)
                {
                        Constant c = child as Constant;
-                       if (c != null)
-                               return new EmptyConstantCast (c, type);
+                       if (c != null) {
+                               var enum_constant = c as EnumConstant;
+                               if (enum_constant != null)
+                                       c = enum_constant.Child;
+
+                               if (!(c is ReducedExpression.ReducedConstantExpression)) {
+                                       if (c.Type == type)
+                                               return c;
+
+                                       var res = c.ConvertImplicitly (type);
+                                       if (res != null)
+                                               return res;
+                               }
+                       }
 
                        EmptyCast e = child as EmptyCast;
                        if (e != null)
@@ -1536,7 +1655,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Constant ConvertExplicitly(bool in_checked_context, TypeSpec target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (Child.Type == target_type)
                                return Child;
@@ -1680,7 +1799,11 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        base.Emit (ec);
+                       Emit (ec, mode);
+               }
 
+               public static void Emit (EmitContext ec, Mode mode)
+               {
                        if (ec.HasSet (EmitContext.Options.CheckedScope)) {
                                switch (mode){
                                case Mode.I1_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
@@ -1949,7 +2072,7 @@ namespace Mono.CSharp {
        //
        public class ReducedExpression : Expression
        {
-               sealed class ReducedConstantExpression : EmptyConstantCast
+               public sealed class ReducedConstantExpression : EmptyConstantCast
                {
                        readonly Expression orig_expr;
 
@@ -1959,6 +2082,12 @@ namespace Mono.CSharp {
                                this.orig_expr = orig_expr;
                        }
 
+                       public Expression OriginalExpression {
+                               get {
+                                       return orig_expr;
+                               }
+                       }
+
                        public override Constant ConvertImplicitly (TypeSpec target_type)
                        {
                                Constant c = base.ConvertImplicitly (target_type);
@@ -2032,6 +2161,11 @@ namespace Mono.CSharp {
                        {
                                stm.EmitStatement (ec);
                        }
+
+                       public override void FlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               stm.FlowAnalysis (fc);
+                       }
                }
 
                readonly Expression expr, orig_expr;
@@ -2135,6 +2269,11 @@ namespace Mono.CSharp {
                        expr.EmitBranchable (ec, target, on_true);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+               }
+
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        return orig_expr.MakeExpression (ctx);
@@ -2230,7 +2369,38 @@ namespace Mono.CSharp {
                {
                        throw new InternalErrorException ("Missing Resolve call");
                }
+       }
 
+       public class UnreachableExpression : Expression
+       {
+               public UnreachableExpression (Expression expr)
+               {
+                       this.loc = expr.Location;
+               }
+
+               public override Expression CreateExpressionTree (ResolveContext ec)
+               {
+                       // TODO: is it ok
+                       throw new NotImplementedException ();
+               }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       fc.Report.Warning (429, 4, loc, "Unreachable expression code detected");
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+               }
+
+               public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
+               {
+               }
        }
 
        //
@@ -2361,19 +2531,12 @@ namespace Mono.CSharp {
 
                protected override Expression DoResolve (ResolveContext rc)
                {
-                       var e = SimpleNameResolve (rc, null, false);
-
-                       var fe = e as FieldExpr;
-                       if (fe != null) {
-                               fe.VerifyAssignedStructField (rc, null);
-                       }
-
-                       return e;
+                       return SimpleNameResolve (rc, null);
                }
 
                public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
                {
-                       return SimpleNameResolve (ec, right_side, false);
+                       return SimpleNameResolve (ec, right_side);
                }
 
                protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ctx)
@@ -2381,7 +2544,7 @@ namespace Mono.CSharp {
                        if (ctx.CurrentType != null) {
                                var member = MemberLookup (ctx, false, ctx.CurrentType, Name, 0, MemberLookupRestrictions.ExactArity, loc) as MemberExpr;
                                if (member != null) {
-                                       member.Error_UnexpectedKind (ctx, member, "type", member.KindName, loc);
+                                       Error_UnexpectedKind (ctx, member, "type", member.KindName, loc);
                                        return;
                                }
                        }
@@ -2397,7 +2560,7 @@ namespace Mono.CSharp {
 
                        retval = ctx.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc);
                        if (retval != null) {
-                               Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, Arity, loc);
+                               Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, loc);
                                return;
                        }
 
@@ -2420,15 +2583,15 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
+               public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
                {
-                       FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, LookupMode.Normal, loc);
+                       FullNamedExpression fne = mc.LookupNamespaceOrType (Name, Arity, LookupMode.Normal, loc);
 
                        if (fne != null) {
                                if (fne.Type != null && Arity > 0) {
                                        if (HasTypeArguments) {
                                                GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
-                                               if (ct.ResolveAsType (ec) == null)
+                                               if (ct.ResolveAsType (mc) == null)
                                                        return null;
 
                                                return ct;
@@ -2444,21 +2607,21 @@ namespace Mono.CSharp {
                                        return fne;
                        }
 
-                       if (Arity == 0 && Name == "dynamic" && ec.Module.Compiler.Settings.Version > LanguageVersion.V_3) {
-                               if (!ec.Module.PredefinedAttributes.Dynamic.IsDefined) {
-                                       ec.Module.Compiler.Report.Error (1980, Location,
+                       if (Arity == 0 && Name == "dynamic" && mc.Module.Compiler.Settings.Version > LanguageVersion.V_3) {
+                               if (!mc.Module.PredefinedAttributes.Dynamic.IsDefined) {
+                                       mc.Module.Compiler.Report.Error (1980, Location,
                                                "Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?",
-                                               ec.Module.PredefinedAttributes.Dynamic.GetSignatureForError ());
+                                               mc.Module.PredefinedAttributes.Dynamic.GetSignatureForError ());
                                }
 
                                fne = new DynamicTypeExpr (loc);
-                               fne.ResolveAsType (ec);
+                               fne.ResolveAsType (mc);
                        }
 
                        if (fne != null)
                                return fne;
 
-                       Error_TypeOrNamespaceNotFound (ec);
+                       Error_TypeOrNamespaceNotFound (mc);
                        return null;
                }
 
@@ -2626,7 +2789,7 @@ namespace Mono.CSharp {
                                                } else {
                                                        var me = MemberLookup (rc, false, rc.CurrentType, Name, Arity, restrictions & ~MemberLookupRestrictions.InvocableOnly, loc) as MemberExpr;
                                                        if (me != null) {
-                                                               me.Error_UnexpectedKind (rc, me, "method group", me.KindName, loc);
+                                                               Error_UnexpectedKind (rc, me, "method group", me.KindName, loc);
                                                                return ErrorExpression.Instance;
                                                        }
                                                }
@@ -2634,12 +2797,15 @@ namespace Mono.CSharp {
                                                e = rc.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc);
                                                if (e != null) {
                                                        if (e.Type.Arity != Arity) {
-                                                               Error_TypeArgumentsCannotBeUsed (rc, e.Type, Arity, loc);
+                                                               Error_TypeArgumentsCannotBeUsed (rc, e.Type, loc);
                                                                return e;
                                                        }
 
                                                        if (e is TypeExpr) {
-                                                               e.Error_UnexpectedKind (rc, e, "variable", e.ExprClassName, loc);
+                                                               // TypeExpression does not have correct location
+                                                               if (e is TypeExpression)
+                                                                       e = new TypeExpression (e.Type, loc);
+
                                                                return e;
                                                        }
                                                }
@@ -2661,19 +2827,19 @@ namespace Mono.CSharp {
                        }
                }
                
-               Expression SimpleNameResolve (ResolveContext ec, Expression right_side, bool intermediate)
+               Expression SimpleNameResolve (ResolveContext ec, Expression right_side)
                {
                        Expression e = LookupNameExpression (ec, right_side == null ? MemberLookupRestrictions.ReadAccess : MemberLookupRestrictions.None);
 
                        if (e == null)
                                return null;
 
-                       if (right_side != null) {
-                               if (e is FullNamedExpression && e.eclass != ExprClass.Unresolved) {
-                                       e.Error_UnexpectedKind (ec, e, "variable", e.ExprClassName, loc);
-                                   return null;
-                               }
+                       if (e is FullNamedExpression && e.eclass != ExprClass.Unresolved) {
+                               Error_UnexpectedKind (ec, e, "variable", e.ExprClassName, loc);
+                               return e;
+                       }
 
+                       if (right_side != null) {
                                e = e.ResolveLValue (ec, right_side);
                        } else {
                                e = e.Resolve (ec);
@@ -2726,7 +2892,7 @@ namespace Mono.CSharp {
 
                        TypeExpr te = fne as TypeExpr;
                        if (te == null) {
-                               fne.Error_UnexpectedKind (mc, fne, "type", fne.ExprClassName, loc);
+                               Error_UnexpectedKind (mc, fne, "type", fne.ExprClassName, loc);
                                return null;
                        }
 
@@ -2890,7 +3056,21 @@ namespace Mono.CSharp {
                                //
                                TypeSpec[] targs = null;
                                if (method.DeclaringType != InstanceExpression.Type) {
-                                       var base_override = MemberCache.FindMember (InstanceExpression.Type, new MemberFilter (method), BindingRestriction.InstanceOnly | BindingRestriction.OverrideOnly) as MethodSpec;
+                                       //
+                                       // Candidate can have inflated MVAR parameters and we need to find
+                                       // base match for original definition not inflated parameter types
+                                       //
+                                       var parameters = method.Parameters;
+                                       if (method.Arity > 0) {
+                                               parameters = ((IParametersMember) method.MemberDefinition).Parameters;
+                                               var inflated = method.DeclaringType as InflatedTypeSpec;
+                                               if (inflated != null) {
+                                                       parameters = parameters.Inflate (inflated.CreateLocalInflator (rc));
+                                               }
+                                       }
+
+                                       var filter = new MemberFilter (method.Name, method.Arity, MemberKind.Method, parameters, null);
+                                       var base_override = MemberCache.FindMember (InstanceExpression.Type, filter, BindingRestriction.InstanceOnly | BindingRestriction.OverrideOnly) as MethodSpec;
                                        if (base_override != null && base_override.DeclaringType != method.DeclaringType) {
                                                if (base_override.IsGeneric)
                                                        targs = method.TypeArguments;
@@ -2934,6 +3114,7 @@ namespace Mono.CSharp {
                        // Only base will allow this invocation to happen.
                        //
                        if (method.IsAbstract) {
+                               rc.Report.SymbolRelatedToPreviousError (method);
                                Error_CannotCallAbstractBase (rc, method.GetSignatureForError ());
                        }
 
@@ -3035,6 +3216,12 @@ namespace Mono.CSharp {
                                member.GetSignatureForError (), qualifier.GetSignatureForError (), rc.CurrentType.GetSignatureForError ());
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (InstanceExpression != null)
+                               InstanceExpression.FlowAnalysis (fc);
+               }
+
                public bool ResolveInstanceExpression (ResolveContext rc, Expression rhs)
                {
                        if (!ResolveInstanceExpressionCore (rc, rhs))
@@ -3043,16 +3230,44 @@ namespace Mono.CSharp {
                        //
                        // Check intermediate value modification which won't have any effect
                        //
-                       if (rhs != null && InstanceExpression.Type.IsStruct &&
-                               (InstanceExpression is PropertyExpr || InstanceExpression is IndexerExpr || InstanceExpression is Invocation)) {
+                       if (rhs != null && InstanceExpression.Type.IsStruct) {
+                               var fexpr = InstanceExpression as FieldExpr;
+                               if (fexpr != null) {
+                                       if (!fexpr.Spec.IsReadOnly || rc.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.ConstructorScope))
+                                               return true;
+
+                                       if (fexpr.IsStatic) {
+                                               rc.Report.Error (1650, loc, "Fields of static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)",
+                                                       fexpr.GetSignatureForError ());
+                                       } else {
+                                               rc.Report.Error (1648, loc, "Members of readonly field `{0}' cannot be modified (except in a constructor or a variable initializer)",
+                                                       fexpr.GetSignatureForError ());
+                                       }
 
-                               if (rc.CurrentInitializerVariable != null) {
-                                       rc.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
-                                               InstanceExpression.Type.GetSignatureForError (), InstanceExpression.GetSignatureForError ());
-                               } else {
-                                       rc.Report.Error (1612, loc,
-                                               "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
-                                               InstanceExpression.GetSignatureForError ());
+                                       return true;
+                               }
+
+                               if (InstanceExpression is PropertyExpr || InstanceExpression is IndexerExpr || InstanceExpression is Invocation) {
+                                       if (rc.CurrentInitializerVariable != null) {
+                                               rc.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
+                                                       InstanceExpression.Type.GetSignatureForError (), InstanceExpression.GetSignatureForError ());
+                                       } else {
+                                               rc.Report.Error (1612, loc,
+                                                       "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
+                                                       InstanceExpression.GetSignatureForError ());
+                                       }
+
+                                       return true;
+                               }
+
+                               var lvr = InstanceExpression as LocalVariableReference;
+                               if (lvr != null) {
+
+                                       if (!lvr.local_info.IsReadonly)
+                                               return true;
+
+                                       rc.Report.Error (1654, loc, "Cannot assign to members of `{0}' because it is a `{1}'",
+                                               InstanceExpression.GetSignatureForError (), lvr.local_info.GetReadOnlyContext ());
                                }
                        }
 
@@ -3109,15 +3324,7 @@ namespace Mono.CSharp {
                                                DeclaringType.GetSignatureForError (), rc.CurrentType.GetSignatureForError ());
                                }
 
-                               InstanceExpression = new This (loc);
-                               if (this is FieldExpr && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) {
-                                       using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
-                                               InstanceExpression = InstanceExpression.Resolve (rc);
-                                       }
-                               } else {
-                                       InstanceExpression = InstanceExpression.Resolve (rc);
-                               }
-
+                               InstanceExpression = new This (loc).Resolve (rc);
                                return false;
                        }
 
@@ -3125,29 +3332,17 @@ namespace Mono.CSharp {
                        if (me != null) {
                                me.ResolveInstanceExpressionCore (rc, rhs);
 
-                               // Using this check to detect probing instance expression resolve
-                               if (!rc.OmitStructFlowAnalysis) {
-                                       var fe = me as FieldExpr;
-                                       if (fe != null && fe.IsMarshalByRefAccess (rc)) {
-                                               rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
-                                               rc.Report.Warning (1690, 1, loc,
-                                                       "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
-                                                       me.GetSignatureForError ());
-                                       }
+                               var fe = me as FieldExpr;
+                               if (fe != null && fe.IsMarshalByRefAccess (rc)) {
+                                       rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
+                                       rc.Report.Warning (1690, 1, loc,
+                                               "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
+                                               me.GetSignatureForError ());
                                }
 
                                return true;
                        }
 
-                       //
-                       // Run member-access postponed check once we know that
-                       // the expression is not field expression which is the only
-                       // expression which can use uninitialized this
-                       //
-                       if (InstanceExpression is This && !(this is FieldExpr) && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) {
-                               ((This)InstanceExpression).CheckStructThisDefiniteAssignment (rc);
-                       }
-
                        //
                        // Additional checks for l-value member access
                        //
@@ -3294,8 +3489,12 @@ namespace Mono.CSharp {
                        if (ExtensionExpression == null)
                                return null;
 
+                       var cand = candidates;
                        arguments.Insert (0, new Argument (ExtensionExpression, Argument.AType.ExtensionType));
                        var res = base.OverloadResolve (ec, ref arguments, ehandler ?? this, restr);
+                       
+                       // Restore candidates in case we are running in probing mode 
+                       candidates = cand;
 
                        // Store resolved argument and restore original arguments
                        if (res == null) {
@@ -3358,6 +3557,8 @@ namespace Mono.CSharp {
        /// </summary>
        public class MethodGroupExpr : MemberExpr, OverloadResolver.IBaseMembersProvider
        {
+               static readonly MemberSpec[] Excluded = new MemberSpec[0];
+
                protected IList<MemberSpec> Methods;
                MethodSpec best_candidate;
                TypeSpec best_candidate_return;
@@ -3407,6 +3608,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool IsConditionallyExcluded {
+                       get {
+                               return Methods == Excluded;
+                       }
+               }
+
                public override bool IsInstance {
                        get {
                                if (best_candidate != null)
@@ -3416,6 +3623,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public override bool IsSideEffectFree {
+                       get {
+                               return InstanceExpression == null || InstanceExpression.IsSideEffectFree;
+                       }
+               }
+
                public override bool IsStatic {
                        get {
                                if (best_candidate != null)
@@ -3470,7 +3683,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (best_candidate.IsConditionallyExcluded (ec, loc))
+                       if (IsConditionallyExcluded)
                                ec.Report.Error (765, loc,
                                        "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree");
                        
@@ -3565,7 +3778,7 @@ namespace Mono.CSharp {
                                                        InstanceExpression = ProbeIdenticalTypeName (ec, InstanceExpression, simple_name);
                                                }
 
-                                               InstanceExpression.Resolve (ec);
+                                               InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup | ResolveFlags.Type);
                                        }
                                }
 
@@ -3595,6 +3808,10 @@ namespace Mono.CSharp {
                                ErrorIsInaccesible (ec, best_candidate.GetSignatureForError (), loc);
                        }
 
+                       // Speed up the check by not doing it on disallowed targets
+                       if (best_candidate_return.Kind == MemberKind.Void && best_candidate.IsConditionallyExcluded (ec))
+                               Methods = Excluded;
+
                        return this;
                }
 
@@ -3639,10 +3856,9 @@ namespace Mono.CSharp {
                //
                public virtual MethodGroupExpr LookupExtensionMethod (ResolveContext rc)
                {
-                       if (InstanceExpression == null)
+                       if (InstanceExpression == null || InstanceExpression.eclass == ExprClass.Type)
                                return null;
 
-                       InstanceExpression = InstanceExpression.Resolve (rc);
                        if (!IsExtensionMethodArgument (InstanceExpression))
                                return null;
 
@@ -4360,6 +4576,11 @@ namespace Mono.CSharp {
                                                                arg_moved = true;
                                                        }
 
+                                                       if (arguments == orig_args) {
+                                                               arguments = new Arguments (orig_args.Count);
+                                                               arguments.AddRange (orig_args);
+                                                       }
+
                                                        arguments[index] = arguments[i];
                                                        arguments[i] = temp;
 
@@ -4668,7 +4889,7 @@ namespace Mono.CSharp {
                                // is used as argument or delegate conversion
                                //
                                if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) {
-                                       return 2;
+                                       return parameter.IsDelegate && argument.Expr is AnonymousMethodExpression ? 2 : 3;
                                }
                        }
 
@@ -4875,8 +5096,7 @@ namespace Mono.CSharp {
                                                }
 
                                                // Restore expanded arguments
-                                               if (candidate_args != args)
-                                                       candidate_args = args;
+                                               candidate_args = args;
                                        }
                                } while (best_candidate_rate != 0 && (type_members = base_provider.GetBaseMembers (type_members[0].DeclaringType.BaseType)) != null);
 
@@ -5081,7 +5301,7 @@ namespace Mono.CSharp {
 
                        if (ta_count != best_candidate.Arity && (ta_count > 0 || ((IParametersMember) best_candidate).Parameters.IsEmpty)) {
                                var mg = new MethodGroupExpr (new [] { best_candidate }, best_candidate.DeclaringType, loc);
-                               mg.Error_TypeArgumentsCannotBeUsed (rc, best_candidate, ta_count, loc);
+                               mg.Error_TypeArgumentsCannotBeUsed (rc, best_candidate, loc);
                                return;
                        }
 
@@ -5114,7 +5334,7 @@ namespace Mono.CSharp {
                                                if (ms.TypeArguments != null)
                                                        constr_ok = new ConstraintChecker (rc.MemberContext).CheckAll (ms.GetGenericMethodDefinition (), ms.TypeArguments, ms.Constraints, loc);
 
-                                               if (ta_count == 0) {
+                                               if (ta_count == 0 && ms.TypeArguments == null) {
                                                        if (custom_errors != null && custom_errors.TypeInferenceFailed (rc, best_candidate))
                                                                return;
 
@@ -5169,6 +5389,9 @@ namespace Mono.CSharp {
 
                        for (; a_idx < arg_count; a_idx++, ++a_pos) {
                                a = args[a_idx];
+                               if (a == null)
+                                       continue;
+
                                if (p_mod != Parameter.Modifier.PARAMS) {
                                        p_mod = pd.FixedParameters[a_idx].ModFlags;
                                        pt = ptypes[a_idx];
@@ -5210,7 +5433,7 @@ namespace Mono.CSharp {
                                                                "The best overloaded method match for `{0}' does not contain a parameter named `{1}'",
                                                                TypeManager.CSharpSignature (member), na.Name);
                                                }
-                                       } else if (args[name_index] != a) {
+                                       } else if (args[name_index] != a && args[name_index] != null) {
                                                if (IsDelegateInvoke)
                                                        ec.Report.SymbolRelatedToPreviousError (DelegateType);
                                                else
@@ -5230,7 +5453,7 @@ namespace Mono.CSharp {
                                        return false;
                                }
 
-                               Expression conv = null;
+                               Expression conv;
                                if (a.ArgType == Argument.AType.ExtensionType) {
                                        if (a.Expr.Type == pt || TypeSpecComparer.IsEqual (a.Expr.Type, pt)) {
                                                conv = a.Expr;
@@ -5255,6 +5478,7 @@ namespace Mono.CSharp {
                                        params_initializers.Add (a.Expr);
                                        args.RemoveAt (a_idx--);
                                        --arg_count;
+                                       a.Expr = conv;
                                        continue;
                                }
 
@@ -5524,18 +5748,14 @@ namespace Mono.CSharp {
                                        // "a.b" is initialized, not whether the whole struct "a" is initialized.
 
                                        if (lvalue_instance) {
-                                               using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
-                                                       bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess;
+                                               bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess;
 
-                                                       Expression right_side =
-                                                               out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
+                                               Expression right_side =
+                                                       out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
 
-                                                       InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
-                                               }
+                                               InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
                                        } else {
-                                               using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
-                                                       InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
-                                               }
+                                               InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
                                        }
 
                                        if (InstanceExpression == null)
@@ -5548,10 +5768,6 @@ namespace Mono.CSharp {
                        var fb = spec as FixedFieldSpec;
                        IVariableReference var = InstanceExpression as IVariableReference;
 
-                       if (lvalue_instance && var != null && var.VariableInfo != null) {
-                               var.VariableInfo.SetStructFieldAssigned (ec, Name);
-                       }
-
                        if (fb != null) {
                                IFixedExpression fe = InstanceExpression as IFixedExpression;
                                if (!ec.HasSet (ResolveContext.Options.FixedInitializerScope) && (fe == null || !fe.IsFixed)) {
@@ -5575,15 +5791,50 @@ namespace Mono.CSharp {
                        //
                        if (var != null && var.VariableInfo != null && InstanceExpression.Type.IsStruct) {
                                variable_info = var.VariableInfo.GetStructFieldInfo (Name);
-                               if (rhs != null && variable_info != null)
-                                       variable_info.SetStructFieldAssigned (ec, Name);
                        }
 
                        eclass = ExprClass.Variable;
                        return this;
                }
 
-               public void VerifyAssignedStructField (ResolveContext rc, Expression rhs)
+               public void SetFieldAssigned (FlowAnalysisContext fc)
+               {
+                       if (!IsInstance)
+                               return;
+
+                       bool lvalue_instance = spec.DeclaringType.IsStruct;
+                       if (lvalue_instance) {
+                               var var = InstanceExpression as IVariableReference;
+                               if (var != null && var.VariableInfo != null) {
+                                       fc.SetStructFieldAssigned (var.VariableInfo, Name);
+                               }
+                       }
+
+                       var fe = InstanceExpression as FieldExpr;
+                       if (fe != null || lvalue_instance) {
+                               if (fe == null)
+                                       return;
+
+                               /*
+                               while (fe.InstanceExpression is FieldExpr) {
+                                       fe = (FieldExpr) fe.InstanceExpression;
+                                       if (!fe.Spec.DeclaringType.IsStruct)
+                                               continue;
+
+                                       if (fe.VariableInfo != null && fc.IsStructFieldDefinitelyAssigned (fe.VariableInfo, fe.Name)) {
+                                               fc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
+                                       }
+                               }
+
+                               fe.InstanceExpression.FlowAnalysis (fc);
+                               */
+                       } else {
+                               InstanceExpression.FlowAnalysis (fc);
+                       }
+               }
+
+
+               public void VerifyAssignedStructField (FlowAnalysisContext fc)
                {
                        var fe = this;
 
@@ -5592,14 +5843,8 @@ namespace Mono.CSharp {
                                if (var != null) {
                                        var vi = var.VariableInfo;
 
-                                       if (vi != null && !vi.IsStructFieldAssigned (rc, fe.Name) && (rhs == null || !fe.type.IsStruct)) {
-                                               if (rhs != null) {
-                                                       rc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
-                                               } else {
-                                                       rc.Report.Error (170, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
-                                               }
-
-                                               return;
+                                       if (vi != null && !fc.IsStructFieldDefinitelyAssigned (vi, fe.Name) && !fe.type.IsStruct) {
+                                               fc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
                                        }
                                }
 
@@ -5608,43 +5853,49 @@ namespace Mono.CSharp {
                        } while (fe != null);
                }
 
-               static readonly int [] codes = {
-                       191,    // instance, write access
-                       192,    // instance, out access
-                       198,    // static, write access
-                       199,    // static, out access
-                       1648,   // member of value instance, write access
-                       1649,   // member of value instance, out access
-                       1650,   // member of value static, write access
-                       1651    // member of value static, out access
-               };
-
-               static readonly string [] msgs = {
-                       /*0191*/ "A readonly field `{0}' cannot be assigned to (except in a constructor or a variable initializer)",
-                       /*0192*/ "A readonly field `{0}' cannot be passed ref or out (except in a constructor)",
-                       /*0198*/ "A static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)",
-                       /*0199*/ "A static readonly field `{0}' cannot be passed ref or out (except in a static constructor)",
-                       /*1648*/ "Members of readonly field `{0}' cannot be modified (except in a constructor or a variable initializer)",
-                       /*1649*/ "Members of readonly field `{0}' cannot be passed ref or out (except in a constructor)",
-                       /*1650*/ "Fields of static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)",
-                       /*1651*/ "Fields of static readonly field `{0}' cannot be passed ref or out (except in a static constructor)"
-               };
-
-               // The return value is always null.  Returning a value simplifies calling code.
-               Expression Report_AssignToReadonly (ResolveContext ec, Expression right_side)
-               {
-                       int i = 0;
-                       if (right_side == EmptyExpression.OutAccess || right_side == EmptyExpression.LValueMemberOutAccess)
-                               i += 1;
-                       if (IsStatic)
-                               i += 2;
-                       if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess)
-                               i += 4;
-                       ec.Report.Error (codes [i], loc, msgs [i], GetSignatureForError ());
+               Expression Error_AssignToReadonly (ResolveContext rc, Expression right_side)
+               {
+                       // The return value is always null.  Returning a value simplifies calling code.
+       
+                       if (right_side == EmptyExpression.OutAccess) {
+                               if (IsStatic) {
+                                       rc.Report.Error (199, loc, "A static readonly field `{0}' cannot be passed ref or out (except in a static constructor)",
+                                               GetSignatureForError ());
+                               } else {
+                                       rc.Report.Error (192, loc, "A readonly field `{0}' cannot be passed ref or out (except in a constructor)",
+                                               GetSignatureForError ());
+                               }
+
+                               return null;
+                       }
+
+                       if (right_side == EmptyExpression.LValueMemberAccess) {
+                               // Already reported as CS1648/CS1650
+                               return null;
+                       }
+
+                       if (right_side == EmptyExpression.LValueMemberOutAccess) {
+                               if (IsStatic) {
+                                       rc.Report.Error (1651, loc, "Fields of static readonly field `{0}' cannot be passed ref or out (except in a static constructor)",
+                                               GetSignatureForError ());
+                               } else {
+                                       rc.Report.Error (1649, loc, "Members of readonly field `{0}' cannot be passed ref or out (except in a constructor)",
+                                               GetSignatureForError ());
+                               }
+                               return null;
+                       }
+
+                       if (IsStatic) {
+                               rc.Report.Error (198, loc, "A static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)",
+                                       GetSignatureForError ());
+                       } else {
+                               rc.Report.Error (191, loc, "A readonly field `{0}' cannot be assigned to (except in a constructor or a variable initializer)",
+                                       GetSignatureForError ());
+                       }
 
                        return null;
                }
-               
+
                override public Expression DoResolveLValue (ResolveContext ec, Expression right_side)
                {
                        if (spec is FixedFieldSpec) {
@@ -5669,19 +5920,19 @@ namespace Mono.CSharp {
                        if (spec.IsReadOnly) {
                                // InitOnly fields can only be assigned in constructors or initializers
                                if (!ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.ConstructorScope))
-                                       return Report_AssignToReadonly (ec, right_side);
+                                       return Error_AssignToReadonly (ec, right_side);
 
                                if (ec.HasSet (ResolveContext.Options.ConstructorScope)) {
 
                                        // InitOnly fields cannot be assigned-to in a different constructor from their declaring type
                                        if (ec.CurrentMemberDefinition.Parent.PartialContainer.Definition != spec.DeclaringType.GetDefinition ())
-                                               return Report_AssignToReadonly (ec, right_side);
+                                               return Error_AssignToReadonly (ec, right_side);
                                        // static InitOnly fields cannot be assigned-to in an instance constructor
                                        if (IsStatic && !ec.IsStatic)
-                                               return Report_AssignToReadonly (ec, right_side);
+                                               return Error_AssignToReadonly (ec, right_side);
                                        // instance constructors can't modify InitOnly fields of other instances of the same type
                                        if (!IsStatic && !(InstanceExpression is This))
-                                               return Report_AssignToReadonly (ec, right_side);
+                                               return Error_AssignToReadonly (ec, right_side);
                                }
                        }
 
@@ -5696,6 +5947,23 @@ namespace Mono.CSharp {
                        return this;
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       var var = InstanceExpression as IVariableReference;
+                       if (var != null) {
+                               var vi = var.VariableInfo;
+                               if (vi != null && !fc.IsStructFieldDefinitelyAssigned (vi, Name)) {
+                                       fc.Report.Error (170, loc, "Use of possibly unassigned field `{0}'", Name);
+                                       return;
+                               }
+
+                               if (TypeSpec.IsValueType (InstanceExpression.Type))
+                                       return;
+                       }
+
+                       base.FlowAnalysis (fc);
+               }
+
                public override int GetHashCode ()
                {
                        return spec.GetHashCode ();
@@ -6102,7 +6370,7 @@ namespace Mono.CSharp {
                                        }
                                }
                        } else {
-                               args = arguments == null ? new Arguments (1) : arguments;
+                               args = arguments ?? new Arguments (1);
 
                                if (leave_copy) {
                                        source.Emit (ec);
@@ -6316,7 +6584,7 @@ namespace Mono.CSharp {
                                                best_candidate.GetSignatureForError ());
                                        return false;
                                }
-                       } else if (!best_candidate.Get.IsAccessible (rc)) {
+                       } else if (!best_candidate.Get.IsAccessible (rc) || !best_candidate.Get.DeclaringType.IsAccessible (rc)) {
                                if (best_candidate.HasDifferentAccessibility) {
                                        rc.Report.SymbolRelatedToPreviousError (best_candidate.Get);
                                        rc.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because the get accessor is inaccessible",
@@ -6343,7 +6611,7 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       if (!best_candidate.Set.IsAccessible (rc)) {
+                       if (!best_candidate.Set.IsAccessible (rc) || !best_candidate.Set.DeclaringType.IsAccessible (rc)) {
                                if (best_candidate.HasDifferentAccessibility) {
                                        rc.Report.SymbolRelatedToPreviousError (best_candidate.Set);
                                        rc.Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible",
@@ -6563,6 +6831,11 @@ namespace Mono.CSharp {
                                DoEmit (ec);
                        }
 
+                       protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               return false;
+                       }
+
                        protected override void CloneTo (CloneContext clonectx, Statement target)
                        {
                                // Nothing
@@ -6606,7 +6879,7 @@ namespace Mono.CSharp {
                        // Don't capture temporary variables except when using
                        // state machine redirection and block yields
                        //
-                       if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod is StateMachineInitializer &&
+                       if (ec.CurrentAnonymousMethod is StateMachineInitializer &&
                                (ec.CurrentBlock.Explicit.HasYield || ec.CurrentBlock.Explicit.HasAwait) &&
                                ec.IsVariableCapturingRequired) {
                                AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec);
@@ -6664,10 +6937,6 @@ namespace Mono.CSharp {
                public override VariableInfo VariableInfo {
                        get { return null; }
                }
-
-               public override void VerifyAssigned (ResolveContext rc)
-               {
-               }
        }
 
        ///