Merge branch 'master' into msbuilddll2
[mono.git] / mcs / mcs / ecore.cs
index bb9c3cd251b2f1492600d66cd0cd879e6b67c136..ec0d7a2c60670ce1f4f3caea3dafab0ad30461a8 100644 (file)
@@ -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) {
@@ -707,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;
@@ -918,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.
@@ -989,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 ();
 
@@ -1170,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);
@@ -1177,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);
 
                        //
@@ -1305,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
@@ -2057,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);
@@ -2130,6 +2161,11 @@ namespace Mono.CSharp {
                        {
                                stm.EmitStatement (ec);
                        }
+
+                       public override void FlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               stm.FlowAnalysis (fc);
+                       }
                }
 
                readonly Expression expr, orig_expr;
@@ -2233,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);
@@ -2328,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)
+               {
+               }
        }
 
        //
@@ -2459,14 +2531,7 @@ namespace Mono.CSharp {
 
                protected override Expression DoResolve (ResolveContext rc)
                {
-                       var e = SimpleNameResolve (rc, null);
-
-                       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)
@@ -2479,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;
                                }
                        }
@@ -2724,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;
                                                        }
                                                }
@@ -2770,7 +2835,7 @@ namespace Mono.CSharp {
                                return null;
 
                        if (e is FullNamedExpression && e.eclass != ExprClass.Unresolved) {
-                               e.Error_UnexpectedKind (ec, e, "variable", e.ExprClassName, loc);
+                               Error_UnexpectedKind (ec, e, "variable", e.ExprClassName, loc);
                                return e;
                        }
 
@@ -2827,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;
                        }
 
@@ -2991,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;
@@ -3035,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 ());
                        }
 
@@ -3136,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))
@@ -3144,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 ());
                                }
                        }
 
@@ -3210,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;
                        }
 
@@ -3226,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
                        //
@@ -3463,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;
@@ -3512,6 +3608,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool IsConditionallyExcluded {
+                       get {
+                               return Methods == Excluded;
+                       }
+               }
+
                public override bool IsInstance {
                        get {
                                if (best_candidate != null)
@@ -3523,8 +3625,7 @@ namespace Mono.CSharp {
 
                public override bool IsSideEffectFree {
                        get {
-                               return InstanceExpression != null ?
-                                       InstanceExpression.IsSideEffectFree : true;
+                               return InstanceExpression == null || InstanceExpression.IsSideEffectFree;
                        }
                }
 
@@ -3582,7 +3683,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (best_candidate.IsConditionallyExcluded (ec))
+                       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");
                        
@@ -3707,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;
                }
 
@@ -3754,7 +3859,6 @@ namespace Mono.CSharp {
                        if (InstanceExpression == null || InstanceExpression.eclass == ExprClass.Type)
                                return null;
 
-                       InstanceExpression = InstanceExpression.Resolve (rc);
                        if (!IsExtensionMethodArgument (InstanceExpression))
                                return null;
 
@@ -4992,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);
 
@@ -5231,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;
 
@@ -5286,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];
@@ -5327,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
@@ -5642,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)
@@ -5666,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)) {
@@ -5693,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;
 
@@ -5710,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);
                                        }
                                }
 
@@ -5726,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) {
@@ -5787,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);
                                }
                        }
 
@@ -5814,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 ();
@@ -6434,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",
@@ -6461,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",
@@ -6681,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
@@ -6724,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);
@@ -6782,10 +6937,6 @@ namespace Mono.CSharp {
                public override VariableInfo VariableInfo {
                        get { return null; }
                }
-
-               public override void VerifyAssigned (ResolveContext rc)
-               {
-               }
        }
 
        ///