X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fstatement.cs;h=4f67eb3240f38407e24a36fc3c384b3f60714489;hb=9667b4ef59cf8ce2617dadebb08fe1b85f1ac33d;hp=703e7ba497fef805446a5df389a8fa4f81258816;hpb=3a980691bc2bca44ed45a4dc2fdf8fee8fbb2914;p=mono.git diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs index 703e7ba497f..4f67eb3240f 100644 --- a/mcs/mcs/statement.cs +++ b/mcs/mcs/statement.cs @@ -270,10 +270,14 @@ namespace Mono.CSharp { var da_false = new DefiniteAssignmentBitSet (fc.DefiniteAssignmentOnFalse); fc.DefiniteAssignment = fc.DefiniteAssignmentOnTrue; + var labels = fc.CopyLabelStack (); var res = TrueStatement.FlowAnalysis (fc); + fc.SetLabelStack (labels); + if (FalseStatement == null) { + var c = expr as Constant; if (c != null && !c.IsDefaultValue) return true_returns; @@ -288,14 +292,20 @@ namespace Mono.CSharp { if (true_returns) { fc.DefiniteAssignment = da_false; - return FalseStatement.FlowAnalysis (fc); + + res = FalseStatement.FlowAnalysis (fc); + fc.SetLabelStack (labels); + return res; } var da_true = fc.DefiniteAssignment; fc.DefiniteAssignment = da_false; + res &= FalseStatement.FlowAnalysis (fc); + fc.SetLabelStack (labels); + if (!TrueStatement.IsUnreachable) { if (false_returns || FalseStatement.IsUnreachable) fc.DefiniteAssignment = da_true; @@ -1291,7 +1301,7 @@ namespace Mono.CSharp { // Special case hoisted return value (happens in try/finally scenario) // if (ec.TryFinallyUnwind != null) { - exit_label = TryFinally.EmitRedirectedReturn (ec, async_body); + exit_label = TryFinally.EmitRedirectedReturn (ec, async_body, unwind_protect); } var async_return = (IAssignMethod)storey.HoistedReturnValue; @@ -1301,7 +1311,7 @@ namespace Mono.CSharp { expr.Emit (ec); if (ec.TryFinallyUnwind != null) - exit_label = TryFinally.EmitRedirectedReturn (ec, async_body); + exit_label = TryFinally.EmitRedirectedReturn (ec, async_body, unwind_protect); } ec.Emit (OpCodes.Leave, exit_label); @@ -1450,7 +1460,7 @@ namespace Mono.CSharp { if (ec.TryFinallyUnwind != null && IsLeavingFinally (label.Block)) { var async_body = (AsyncInitializer) ec.CurrentAnonymousMethod; - l = TryFinally.EmitRedirectedJump (ec, async_body, l, label.Block); + l = TryFinally.EmitRedirectedJump (ec, async_body, l, label.Block, unwind_protect); } ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l); @@ -1857,7 +1867,7 @@ namespace Mono.CSharp { if (ec.TryFinallyUnwind != null) { var async_body = (AsyncInitializer) ec.CurrentAnonymousMethod; - l = TryFinally.EmitRedirectedJump (ec, async_body, l, enclosing_loop.Statement as Block); + l = TryFinally.EmitRedirectedJump (ec, async_body, l, enclosing_loop.Statement as Block, unwind_protect); } ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l); @@ -1905,7 +1915,7 @@ namespace Mono.CSharp { if (ec.TryFinallyUnwind != null) { var async_body = (AsyncInitializer) ec.CurrentAnonymousMethod; - l = TryFinally.EmitRedirectedJump (ec, async_body, l, enclosing_loop.Statement as Block); + l = TryFinally.EmitRedirectedJump (ec, async_body, l, enclosing_loop.Statement as Block, unwind_protect); } ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l); @@ -2280,6 +2290,9 @@ namespace Mono.CSharp { public override void Emit (EmitContext ec) { + if (!Variable.IsUsed) + ec.Report.Warning (219, 3, loc, "The constant `{0}' is never used", Variable.Name); + // Nothing to emit, not even sequence point } @@ -2438,6 +2451,12 @@ namespace Mono.CSharp { } } + public bool IsUsed { + get { + return (flags & Flags.Used) != 0; + } + } + public bool IsFixed { get { return (flags & Flags.FixedVariable) != 0; @@ -2527,8 +2546,10 @@ namespace Mono.CSharp { public Expression CreateReferenceExpression (ResolveContext rc, Location loc) { - if (IsConstant && const_value != null) + if (IsConstant && const_value != null) { + SetIsUsed (); return Constant.CreateConstantFromValue (Type, const_value.GetValue (), loc); + } return new LocalVariableReference (this, loc); } @@ -2657,6 +2678,7 @@ namespace Mono.CSharp { AwaitBlock = 1 << 13, FinallyBlock = 1 << 14, CatchBlock = 1 << 15, + HasReferenceToStoreyForInstanceLambdas = 1 << 16, Iterator = 1 << 20, NoFlowAnalysis = 1 << 21, InitializationEmitted = 1 << 22 @@ -3223,9 +3245,10 @@ namespace Mono.CSharp { public override void Emit (EmitContext ec) { - if (Parent != null) { - // TODO: It's needed only when scope has variable (normal or lifted) - ec.BeginScope (GetDebugSymbolScopeIndex ()); + // TODO: It's needed only when scope has variable (normal or lifted) + var scopeIndex = GetDebugSymbolScopeIndex (); + if (scopeIndex > 0) { + ec.BeginScope (scopeIndex); } EmitScopeInitialization (ec); @@ -3236,7 +3259,7 @@ namespace Mono.CSharp { DoEmit (ec); - if (Parent != null) + if (scopeIndex > 0) ec.EndScope (); if (ec.EmitAccurateDebugInfo && HasReachableClosingBrace && !(this is ParametersBlock) && @@ -3257,6 +3280,7 @@ namespace Mono.CSharp { // storey.CreateContainer (); storey.DefineContainer (); + storey.ExpandBaseInterfaces (); if (Original.Explicit.HasCapturedThis && Original.ParametersBlock.TopBlock.ThisReferencesFromChildrenBlock != null) { @@ -3281,7 +3305,7 @@ namespace Mono.CSharp { break; } } - + // // We are the first storey on path and 'this' has to be hoisted // @@ -3349,7 +3373,7 @@ namespace Mono.CSharp { // // If we are state machine with no parent. We can hook into parent without additional - // reference and capture this directly + // reference and capture this directly // ExplicitBlock parent_storey_block = pb; while (parent_storey_block.Parent != null) { @@ -3428,7 +3452,12 @@ namespace Mono.CSharp { storey.Parent.PartialContainer.AddCompilerGeneratedClass (storey); } - public int GetDebugSymbolScopeIndex () + public void DisableDebugScopeIndex () + { + debug_scope_index = -1; + } + + public virtual int GetDebugSymbolScopeIndex () { if (debug_scope_index == 0) debug_scope_index = ++ParametersBlock.debug_scope_index; @@ -3666,6 +3695,15 @@ namespace Mono.CSharp { #region Properties + public bool HasReferenceToStoreyForInstanceLambdas { + get { + return (flags & Flags.HasReferenceToStoreyForInstanceLambdas) != 0; + } + set { + flags = value ? flags | Flags.HasReferenceToStoreyForInstanceLambdas : flags & ~Flags.HasReferenceToStoreyForInstanceLambdas; + } + } + public bool IsAsync { get { return (flags & Flags.HasAsyncModifier) != 0; @@ -3827,6 +3865,11 @@ namespace Mono.CSharp { return res; } + public override int GetDebugSymbolScopeIndex () + { + return 0; + } + public LabeledStatement GetLabel (string name, Block block) { // @@ -6002,7 +6045,7 @@ namespace Mono.CSharp { ec.EmitInt (first_resume_pc); ec.Emit (OpCodes.Sub); - var labels = new Label[resume_points.Count - System.Math.Max (first_catch_resume_pc, 0)]; + var labels = new Label [first_catch_resume_pc > 0 ? first_catch_resume_pc : resume_points.Count]; for (int i = 0; i < labels.Length; ++i) labels[i] = resume_points[i].PrepareForEmit (ec); ec.Emit (OpCodes.Switch, labels); @@ -6954,7 +6997,7 @@ namespace Mono.CSharp { { ExplicitBlock fini; List try_exit_dat; - List