* statement.cs (While, For, Do): These loops can exit through a
Break statement, use this information to tell whether the
statement is the last piece of code.
(Break): Flag that we break.
* codegen.cs (EmitContexts): New `Breaks' state variable.
svn path=/trunk/mcs/; revision=5583
+2002-07-03 Miguel de Icaza <miguel@ximian.com>
+
+ * statement.cs (While, For, Do): These loops can exit through a
+ Break statement, use this information to tell whether the
+ statement is the last piece of code.
+
+ (Break): Flag that we break.
+
+ * codegen.cs (EmitContexts): New `Breaks' state variable.
+
2002-07-03 Martin Baulig <martin@gnome.org>
* class.cs (TypeContainer.MethodModifiersValid): Allow override
2002-07-03 Martin Baulig <martin@gnome.org>
* class.cs (TypeContainer.MethodModifiersValid): Allow override
/// Whether we are inside an unsafe block
/// </summary>
public bool InUnsafe;
/// Whether we are inside an unsafe block
/// </summary>
public bool InUnsafe;
+
+ /// <summary>
+ /// Whether we break from a loop or not
+ /// </summary>
+ public bool Breaks;
/// <summary>
/// Location for this EmitContext
/// <summary>
/// Location for this EmitContext
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
+ bool old_breaks = ec.Breaks;
ec.LoopBegin = ig.DefineLabel ();
ec.LoopEnd = ig.DefineLabel ();
ec.InLoop = true;
ig.MarkLabel (loop);
ec.LoopBegin = ig.DefineLabel ();
ec.LoopEnd = ig.DefineLabel ();
ec.InLoop = true;
ig.MarkLabel (loop);
EmbeddedStatement.Emit (ec);
EmbeddedStatement.Emit (ec);
+ bool breaks = ec.Breaks;
ig.MarkLabel (ec.LoopBegin);
//
ig.MarkLabel (ec.LoopBegin);
//
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
+ ec.Breaks = old_breaks;
//
// Inform whether we are infinite or not
//
// Inform whether we are infinite or not
BoolConstant bc = (BoolConstant) expr;
if (bc.Value == true)
BoolConstant bc = (BoolConstant) expr;
if (bc.Value == true)
+ return breaks == false;
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
+ bool old_breaks = ec.Breaks;
Label while_loop = ig.DefineLabel ();
bool ret;
Label while_loop = ig.DefineLabel ();
bool ret;
Warning_DeadCodeFound (Statement.loc);
ret = false;
} else {
Warning_DeadCodeFound (Statement.loc);
ret = false;
} else {
+ bool breaks;
+
+ ec.Breaks = false;
ig.Emit (OpCodes.Br, ec.LoopBegin);
//
ig.Emit (OpCodes.Br, ec.LoopBegin);
//
- // Inform that we are infinite (ie, `we return')
+ // Inform that we are infinite (ie, `we return'), only
+ // if we do not `break' inside the code.
}
ig.MarkLabel (ec.LoopEnd);
} else {
}
ig.MarkLabel (ec.LoopEnd);
} else {
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
+ ec.Breaks = old_breaks;
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
+ bool old_breaks = ec.Breaks;
Label loop = ig.DefineLabel ();
if (InitStatement != null)
Label loop = ig.DefineLabel ();
if (InitStatement != null)
//
if (Test != null)
EmitBoolExpression (ec, Test, ec.LoopEnd, false);
//
if (Test != null)
EmitBoolExpression (ec, Test, ec.LoopEnd, false);
+ bool breaks = ec.Breaks;
+
ig.MarkLabel (ec.LoopBegin);
if (!(Increment is EmptyStatement))
Increment.Emit (ec);
ig.MarkLabel (ec.LoopBegin);
if (!(Increment is EmptyStatement))
Increment.Emit (ec);
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
+ ec.Breaks = old_breaks;
+
//
// Inform whether we are infinite or not
//
//
// Inform whether we are infinite or not
//
BoolConstant bc = (BoolConstant) Test;
if (bc.Value)
BoolConstant bc = (BoolConstant) Test;
if (bc.Value)
+ return breaks == false;
Report.Error (139, loc, "No enclosing loop or switch to continue to");
return false;
}
Report.Error (139, loc, "No enclosing loop or switch to continue to");
return false;
}
ig.Emit (OpCodes.Br, ec.LoopEnd);
return false;
ig.Emit (OpCodes.Br, ec.LoopEnd);
return false;