X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fexpression.cs;h=05abac7fbc3703f4c178919c393977e6d88bdc98;hb=df9535c5a4dd4a3935cbed3acb7566e072814ff1;hp=5729d7581baa508915f3bd10a8835fca1d589bf2;hpb=96a201f7fe81583e494bfaf647055d4f8acf64d3;p=mono.git diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs index 5729d7581ba..05abac7fbc3 100644 --- a/mcs/mcs/expression.cs +++ b/mcs/mcs/expression.cs @@ -83,6 +83,11 @@ namespace Mono.CSharp call.EmitPredefined (ec, oper, arguments, loc); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + arguments.FlowAnalysis (fc); + } + public override SLE.Expression MakeExpression (BuilderContext ctx) { #if STATIC @@ -572,6 +577,19 @@ namespace Mono.CSharp Expr.EmitSideEffect (ec); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + if (Oper == Operator.AddressOf) { + var vr = Expr as VariableReference; + if (vr != null && vr.VariableInfo != null) + fc.SetVariableAssigned (vr.VariableInfo); + + return; + } + + Expr.FlowAnalysis (fc); + } + // // Converts operator to System.Linq.Expressions.ExpressionType enum name // @@ -1274,6 +1292,11 @@ namespace Mono.CSharp EmitCode (ec, false); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + expr.FlowAnalysis (fc); + } + // // Converts operator to System.Linq.Expressions.ExpressionType enum name // @@ -1367,6 +1390,11 @@ namespace Mono.CSharp return this; } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + expr.FlowAnalysis (fc); + } + protected abstract string OperatorName { get; } protected override void CloneTo (CloneContext clonectx, Expression t) @@ -2518,6 +2546,12 @@ namespace Mono.CSharp Error_OperatorCannotBeApplied (ec, left, right, OperName (oper), loc); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + left.FlowAnalysis (fc); + right.FlowAnalysis (fc); + } + // // Converts operator to System.Linq.Expressions.ExpressionType enum name // @@ -4890,6 +4924,11 @@ namespace Mono.CSharp } } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + arguments.FlowAnalysis (fc); + } + public override SLE.Expression MakeExpression (BuilderContext ctx) { if (arguments.Count != 2) @@ -5259,32 +5298,8 @@ namespace Mono.CSharp protected override Expression DoResolve (ResolveContext ec) { expr = expr.Resolve (ec); - - // - // Unreachable code needs different resolve path. For instance for await - // expression to not generate unreachable resumable statement - // - Constant c = expr as Constant; - if (c != null && ec.CurrentBranching != null) { - bool unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable; - - if (c.IsDefaultValue) { - ec.CurrentBranching.CurrentUsageVector.IsUnreachable = true; - true_expr = true_expr.Resolve (ec); - ec.CurrentBranching.CurrentUsageVector.IsUnreachable = unreachable; - - false_expr = false_expr.Resolve (ec); - } else { - true_expr = true_expr.Resolve (ec); - - ec.CurrentBranching.CurrentUsageVector.IsUnreachable = true; - false_expr = false_expr.Resolve (ec); - ec.CurrentBranching.CurrentUsageVector.IsUnreachable = unreachable; - } - } else { - true_expr = true_expr.Resolve (ec); - false_expr = false_expr.Resolve (ec); - } + true_expr = true_expr.Resolve (ec); + false_expr = false_expr.Resolve (ec); if (true_expr == null || false_expr == null || expr == null) return null; @@ -5345,8 +5360,9 @@ namespace Mono.CSharp true_type.GetSignatureForError (), false_type.GetSignatureForError ()); return null; } - } + } + Constant c = expr as Constant; if (c != null) { bool is_false = c.IsDefaultValue; @@ -5392,6 +5408,21 @@ namespace Mono.CSharp ec.MarkLabel (end_target); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + expr.FlowAnalysis (fc); + var expr_fc = fc.DefiniteAssignment; + + fc.DefiniteAssignment = new DefiniteAssignmentBitSet (expr_fc); + true_expr.FlowAnalysis (fc); + var true_fc = fc.DefiniteAssignment; + + fc.DefiniteAssignment = new DefiniteAssignmentBitSet (expr_fc); + false_expr.FlowAnalysis (fc); + + fc.DefiniteAssignment &= true_fc; + } + protected override void CloneTo (CloneContext clonectx, Expression t) { Conditional target = (Conditional) t; @@ -5409,7 +5440,6 @@ namespace Mono.CSharp #region Abstract public abstract HoistedVariable GetHoistedVariable (AnonymousExpression ae); public abstract void SetHasAddressTaken (); - public abstract void VerifyDefiniteAssignment (ResolveContext rc); public abstract bool IsLockedByStatement { get; set; } @@ -5642,17 +5672,17 @@ namespace Mono.CSharp #endregion - public override void VerifyDefiniteAssignment (ResolveContext rc) + public override void FlowAnalysis (FlowAnalysisContext fc) { VariableInfo variable_info = VariableInfo; if (variable_info == null) return; - if (variable_info.IsAssigned (rc)) + if (fc.IsDefinitelyAssigned (variable_info)) return; - rc.Report.Error (165, loc, "Use of unassigned local variable `{0}'", Name); - variable_info.SetAssigned (rc); + fc.Report.Error (165, loc, "Use of unassigned local variable `{0}'", Name); + variable_info.SetAssigned (fc.DefiniteAssignment, true); } public override void SetHasAddressTaken () @@ -5689,8 +5719,6 @@ namespace Mono.CSharp { local_info.SetIsUsed (); - VerifyDefiniteAssignment (ec); - DoResolveBase (ec); return this; } @@ -5705,22 +5733,22 @@ namespace Mono.CSharp local_info.SetIsUsed (); if (local_info.IsReadonly && !ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.UsingInitializerScope)) { - int code; - string msg; - if (rhs == EmptyExpression.OutAccess) { - code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'"; - } else if (rhs == EmptyExpression.LValueMemberAccess) { - code = 1654; msg = "Cannot assign to members of `{0}' because it is a `{1}'"; - } else if (rhs == EmptyExpression.LValueMemberOutAccess) { - code = 1655; msg = "Cannot pass members of `{0}' as ref or out arguments because it is a `{1}'"; - } else if (rhs == EmptyExpression.UnaryAddress) { - code = 459; msg = "Cannot take the address of {1} `{0}'"; + if (rhs == EmptyExpression.LValueMemberAccess) { + // CS1654 already reported } else { - code = 1656; msg = "Cannot assign to `{0}' because it is a `{1}'"; + int code; + string msg; + if (rhs == EmptyExpression.OutAccess) { + code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'"; + } else if (rhs == EmptyExpression.LValueMemberOutAccess) { + code = 1655; msg = "Cannot pass members of `{0}' as ref or out arguments because it is a `{1}'"; + } else if (rhs == EmptyExpression.UnaryAddress) { + code = 459; msg = "Cannot take the address of {1} `{0}'"; + } else { + code = 1656; msg = "Cannot assign to `{0}' because it is a `{1}'"; + } + ec.Report.Error (code, loc, msg, Name, local_info.GetReadOnlyContext ()); } - ec.Report.Error (code, loc, msg, Name, local_info.GetReadOnlyContext ()); - } else if (VariableInfo != null) { - VariableInfo.SetAssigned (ec); } if (eclass == ExprClass.Unresolved) @@ -5840,15 +5868,6 @@ namespace Mono.CSharp Parameter.HasAddressTaken = true; } - void SetAssigned (ResolveContext ec) - { - if (Parameter.HoistedVariant != null) - Parameter.HoistedVariant.IsAssigned = true; - - if (HasOutModifier && ec.DoFlowAnalysis) - ec.CurrentBranching.SetAssigned (VariableInfo); - } - bool DoResolveBase (ResolveContext ec) { if (eclass != ExprClass.Unresolved) @@ -5914,7 +5933,6 @@ namespace Mono.CSharp if (!DoResolveBase (ec)) return null; - VerifyDefiniteAssignment (ec); return this; } @@ -5923,21 +5941,23 @@ namespace Mono.CSharp if (!DoResolveBase (ec)) return null; - SetAssigned (ec); + if (Parameter.HoistedVariant != null) + Parameter.HoistedVariant.IsAssigned = true; + return base.DoResolveLValue (ec, right_side); } - public override void VerifyDefiniteAssignment (ResolveContext rc) + public override void FlowAnalysis (FlowAnalysisContext fc) { VariableInfo variable_info = VariableInfo; if (variable_info == null) return; - if (variable_info.IsAssigned (rc)) + if (fc.IsDefinitelyAssigned (variable_info)) return; - rc.Report.Error (269, loc, "Use of unassigned out parameter `{0}'", Name); - variable_info.SetAssigned (rc); + fc.Report.Error (269, loc, "Use of unassigned out parameter `{0}'", Name); + fc.SetVariableAssigned (variable_info); } } @@ -6201,6 +6221,17 @@ namespace Mono.CSharp return mg.OverloadResolve (ec, ref arguments, null, OverloadResolver.Restrictions.None); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + if (mg.IsConditionallyExcluded) + return; + + mg.FlowAnalysis (fc); + + if (arguments != null) + arguments.FlowAnalysis (fc); + } + public override string GetSignatureForError () { return mg.GetSignatureForError (); @@ -6241,6 +6272,9 @@ namespace Mono.CSharp public override void Emit (EmitContext ec) { + if (mg.IsConditionallyExcluded) + return; + mg.EmitCall (ec, arguments); } @@ -6626,6 +6660,12 @@ namespace Mono.CSharp ec.Emit (OpCodes.Pop); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + if (arguments != null) + arguments.FlowAnalysis (fc); + } + public void AddressOf (EmitContext ec, AddressOp mode) { EmitAddressOf (ec, mode); @@ -6786,6 +6826,11 @@ namespace Mono.CSharp { throw new InternalErrorException ("Missing Resolve call"); } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + throw new InternalErrorException ("Missing Resolve call"); + } public override object Accept (StructuralVisitor visitor) { @@ -7047,6 +7092,17 @@ namespace Mono.CSharp ec.Report.Error (248, loc, "Cannot create an array with a negative size"); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + foreach (var arg in arguments) + arg.FlowAnalysis (fc); + + if (array_data != null) { + foreach (var ad in array_data) + ad.FlowAnalysis (fc); + } + } + bool InitializersContainAwait () { if (array_data == null) @@ -7691,7 +7747,7 @@ namespace Mono.CSharp #endregion - public void CheckStructThisDefiniteAssignment (ResolveContext rc) + void CheckStructThisDefiniteAssignment (FlowAnalysisContext fc) { // // It's null for all cases when we don't need to check `this' @@ -7700,13 +7756,10 @@ namespace Mono.CSharp if (variable_info == null) return; - if (rc.OmitStructFlowAnalysis) + if (fc.IsDefinitelyAssigned (variable_info)) return; - if (!variable_info.IsAssigned (rc)) { - rc.Report.Error (188, loc, - "The `this' object cannot be used before all of its fields are assigned to"); - } + fc.Report.Error (188, loc, "The `this' object cannot be used before all of its fields are assigned to"); } protected virtual void Error_ThisNotAvailable (ResolveContext ec) @@ -7722,6 +7775,11 @@ namespace Mono.CSharp } } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + CheckStructThisDefiniteAssignment (fc); + } + public override HoistedVariable GetHoistedVariable (AnonymousExpression ae) { if (ae == null) @@ -7779,9 +7837,6 @@ namespace Mono.CSharp protected override Expression DoResolve (ResolveContext ec) { ResolveBase (ec); - - CheckStructThisDefiniteAssignment (ec); - return this; } @@ -7790,9 +7845,6 @@ namespace Mono.CSharp if (eclass == ExprClass.Unresolved) ResolveBase (ec); - if (variable_info != null) - variable_info.SetAssigned (ec); - if (type.IsClass){ if (right_side == EmptyExpression.UnaryAddress) ec.Report.Error (459, loc, "Cannot take the address of `this' because it is read-only"); @@ -7828,10 +7880,6 @@ namespace Mono.CSharp { // Nothing } - - public override void VerifyDefiniteAssignment (ResolveContext rc) - { - } public override object Accept (StructuralVisitor visitor) { @@ -8614,50 +8662,25 @@ namespace Mono.CSharp protected override Expression DoResolve (ResolveContext rc) { - var e = DoResolveName (rc, null); - - if (!rc.OmitStructFlowAnalysis) { - var fe = e as FieldExpr; - if (fe != null) { - fe.VerifyAssignedStructField (rc, null); - } - } + var e = LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess); + if (e != null) + e = e.Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.Type | ResolveFlags.MethodGroup); return e; } public override Expression DoResolveLValue (ResolveContext rc, Expression rhs) { - var e = DoResolveName (rc, rhs); - - if (!rc.OmitStructFlowAnalysis) { - var fe = e as FieldExpr; - if (fe != null && fe.InstanceExpression is FieldExpr) { - fe = (FieldExpr) fe.InstanceExpression; - fe.VerifyAssignedStructField (rc, rhs); - } - } + var e = LookupNameExpression (rc, MemberLookupRestrictions.None); - return e; - } - - Expression DoResolveName (ResolveContext rc, Expression right_side) - { - Expression e = LookupNameExpression (rc, right_side == null ? MemberLookupRestrictions.ReadAccess : MemberLookupRestrictions.None); - if (e == null) + if (e is TypeExpr) { + e.Error_UnexpectedKind (rc, ResolveFlags.VariableOrValue, loc); return null; - - if (right_side != null) { - if (e is TypeExpr) { - e.Error_UnexpectedKind (rc, ResolveFlags.VariableOrValue, loc); - return null; - } - - e = e.ResolveLValue (rc, right_side); - } else { - e = e.Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.Type | ResolveFlags.MethodGroup); } + if (e != null) + e = e.ResolveLValue (rc, rhs); + return e; } @@ -8682,32 +8705,22 @@ namespace Mono.CSharp var sn = expr as SimpleName; const ResolveFlags flags = ResolveFlags.VariableOrValue | ResolveFlags.Type; - // - // Resolve the expression with flow analysis turned off, we'll do the definite - // assignment checks later. This is because we don't know yet what the expression - // will resolve to - it may resolve to a FieldExpr and in this case we must do the - // definite assignment check on the actual field and not on the whole struct. - // - using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) { - if (sn != null) { - expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity); + if (sn != null) { + expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity); - // - // Resolve expression which does have type set as we need expression type - // with disable flow analysis as we don't know whether left side expression - // is used as variable or type - // - if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) { - using (rc.With (ResolveContext.Options.DoFlowAnalysis, false)) { - expr = expr.Resolve (rc); - } - } else if (expr is TypeParameterExpr) { - expr.Error_UnexpectedKind (rc, flags, sn.Location); - expr = null; - } - } else { - expr = expr.Resolve (rc, flags); + // + // Resolve expression which does have type set as we need expression type + // with disable flow analysis as we don't know whether left side expression + // is used as variable or type + // + if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) { + expr = expr.Resolve (rc); + } else if (expr is TypeParameterExpr) { + expr.Error_UnexpectedKind (rc, flags, sn.Location); + expr = null; } + } else { + expr = expr.Resolve (rc, flags); } if (expr == null) @@ -8735,16 +8748,6 @@ namespace Mono.CSharp if (me != null) me.ResolveInstanceExpression (rc, null); - // - // Run defined assigned checks on expressions resolved with - // disabled flow-analysis - // - if (sn != null) { - var vr = expr as VariableReference; - if (vr != null) - vr.VerifyDefiniteAssignment (rc); - } - Arguments args = new Arguments (1); args.Add (new Argument (expr)); return new DynamicMemberBinder (Name, args, loc); @@ -8775,16 +8778,6 @@ namespace Mono.CSharp emg.SetTypeArguments (rc, targs); } - // - // Run defined assigned checks on expressions resolved with - // disabled flow-analysis - // - if (sn != null && !errorMode) { - var vr = expr as VariableReference; - if (vr != null) - vr.VerifyDefiniteAssignment (rc); - } - // TODO: it should really skip the checks bellow return emg.Resolve (rc); } @@ -8857,16 +8850,6 @@ namespace Mono.CSharp me.SetTypeArguments (rc, targs); } - // - // Run defined assigned checks on expressions resolved with - // disabled flow-analysis - // - if (sn != null && !(me is FieldExpr && TypeSpec.IsValueType (expr_type))) { - var vr = expr as VariableReference; - if (vr != null) - vr.VerifyDefiniteAssignment (rc); - } - return me; } @@ -9079,6 +9062,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) { using (ctx.With (BuilderContext.Options.CheckedScope, true)) { @@ -9151,6 +9139,11 @@ namespace Mono.CSharp Expr.EmitBranchable (ec, target, on_true); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + Expr.FlowAnalysis (fc); + } + protected override void CloneTo (CloneContext clonectx, Expression t) { UnCheckedExpr target = (UnCheckedExpr) t; @@ -9289,6 +9282,12 @@ namespace Mono.CSharp Report.Error (1742, na.Location, "An element access expression cannot use named argument"); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + Expr.FlowAnalysis (fc); + Arguments.FlowAnalysis (fc); + } + public override string GetSignatureForError () { return Expr.GetSignatureForError (); @@ -9391,6 +9390,11 @@ namespace Mono.CSharp ec.Report.Warning (251, 2, loc, "Indexing an array with a negative index (array indices always start at zero)"); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + ea.FlowAnalysis (fc); + } + // // Load the array arguments into the stack. // @@ -9688,6 +9692,13 @@ namespace Mono.CSharp } } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + // TODO: Check the order + base.FlowAnalysis (fc); + arguments.FlowAnalysis (fc); + } + public override string GetSignatureForError () { return best_candidate.GetSignatureForError (); @@ -10098,6 +10109,11 @@ namespace Mono.CSharp ec.Emit (OpCodes.Call, method); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + source.FlowAnalysis (fc); + } + public override string GetSignatureForError () { return TypeManager.CSharpSignature (method); @@ -10799,6 +10815,12 @@ namespace Mono.CSharp e.EmitStatement (ec); } } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + foreach (var initializer in initializers) + initializer.FlowAnalysis (fc); + } } // @@ -10993,6 +11015,12 @@ namespace Mono.CSharp return instance; } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + base.FlowAnalysis (fc); + initializers.FlowAnalysis (fc); + } + public override object Accept (StructuralVisitor visitor) { return visitor.Visit (this);