if ((FalseStatement != null) &&
!FalseStatement.Resolve (ec))
- return false;
- }
+ return false;
+ }
return true;
}
if (!Statement.Resolve (ec))
ok = false;
- ec.CurrentBranching.Infinite = infinite;
- ec.EndFlowBranching ();
+ ec.CurrentBranching.Infinite = infinite;
+ ec.EndFlowBranching ();
return ok;
}
public override bool Resolve (EmitContext ec)
{
if (ec.ReturnType == null){
- if (Expr != null){
+ if (Expr != null){
if (ec.CurrentAnonymousMethod != null){
Report.Error (1662, loc, String.Format (
"Anonymous method could not be converted to delegate " +
} else if (ec.CurrentBranching.InTryOrCatch (false))
ec.CurrentBranching.AddFinallyVector (
ec.CurrentBranching.CurrentUsageVector);
- else if (ec.CurrentBranching.InLoop ())
+ else if (ec.CurrentBranching.InLoop () || ec.CurrentBranching.InSwitch ())
ec.CurrentBranching.AddBreakVector (
ec.CurrentBranching.CurrentUsageVector);
AddressTaken = 32
}
- Flags flags;
+ public enum ReadOnlyContext: byte {
+ Using,
+ Foreach,
+ Fixed
+ }
+ Flags flags;
+ ReadOnlyContext ro_context;
+
public LocalInfo (Expression type, string name, Block block, Location l)
{
Type = type;
get {
return (flags & Flags.ReadOnly) != 0;
}
- set {
- flags = value ? (flags | Flags.ReadOnly) : (unchecked (flags & ~Flags.ReadOnly));
+ }
+
+ public void SetReadOnlyContext (ReadOnlyContext context)
+ {
+ flags |= Flags.ReadOnly;
+ ro_context = context;
+ }
+
+ public string GetReadOnlyContext ()
+ {
+ if (!ReadOnly)
+ throw new InternalErrorException ("Variable is not readonly");
+
+ switch (ro_context) {
+ case ReadOnlyContext.Fixed:
+ return "fixed variable";
+ case ReadOnlyContext.Foreach:
+ return "foreach iteration variable";
+ case ReadOnlyContext.Using:
+ return "using variable";
}
+ throw new NotImplementedException ();
}
//
return e != null;
}
- //
- // Returns a `ParameterReference' for the given name, or null if there
- // is no such parameter
- //
- public ParameterReference GetParameterReference (string name, Location loc)
- {
- Parameter par;
- int idx;
-
- for (Block b = this; b != null; b = b.Toplevel.Parent) {
- Parameters pars = b.Toplevel.Parameters;
- par = pars.GetParameterByName (name, out idx);
- if (par != null)
- return new ParameterReference (pars, this, idx, name, loc);
- }
- return null;
- }
-
- //
- // Whether the parameter named `name' is local to this block,
- // or false, if the parameter belongs to an encompassing block.
- //
- public bool IsLocalParameter (string name)
- {
- return Toplevel.Parameters.GetParameterByName (name) != null;
- }
-
- //
- // Whether the `name' is a parameter reference
- //
- public bool IsParameterReference (string name)
- {
- Parameter par;
- int idx;
-
- for (Block b = this; b != null; b = b.Toplevel.Parent) {
- par = b.Toplevel.Parameters.GetParameterByName (name, out idx);
- if (par != null)
- return true;
- }
- return false;
- }
-
/// <returns>
/// A list of labels that were not used within this block
/// </returns>
for (int ix = 0; ix < statement_count; ix++){
Statement s = (Statement) statements [ix];
- if (unreachable && !(s is LabeledStatement)) {
- if (s == EmptyStatement.Value)
- s.loc = EndLocation;
+ if (unreachable) {
+ if (s is Block)
+ ((Block) s).unreachable = true;
- if (!s.ResolveUnreachable (ec, !unreachable_shown))
- ok = false;
-
- if (s != EmptyStatement.Value)
+ if (!unreachable_shown && (RootContext.WarningLevel >= 2)) {
+ Report.Warning (
+ 162, loc, "Unreachable code detected");
unreachable_shown = true;
- else
- s.loc = Location.Null;
-
- if (ok && !(s is Block)) {
- statements [ix] = EmptyStatement.Value;
- continue;
}
}
- if (s.Resolve (ec) == false) {
- ok = false;
+ if (!s.Resolve (ec)) {
+ ok = false;
statements [ix] = EmptyStatement.Value;
continue;
}
- num_statements = ix + 1;
+ if (unreachable && !(s is LabeledStatement) && !(s is Block))
+ statements [ix] = EmptyStatement.Value;
+ num_statements = ix + 1;
if (s is LabeledStatement)
unreachable = false;
else
public override bool ResolveUnreachable (EmitContext ec, bool warn)
{
unreachable_shown = true;
+ unreachable = true;
if (warn && (RootContext.WarningLevel >= 2))
Report.Warning (162, loc, "Unreachable code detected");
- if (Implicit)
- return Resolve (ec);
-
- unreachable = true;
-
ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
bool ok = Resolve (ec);
ec.KillFlowBranching ();
}
}
+ //
+ // Returns a `ParameterReference' for the given name, or null if there
+ // is no such parameter
+ //
+ public ParameterReference GetParameterReference (string name, Location loc)
+ {
+ Parameter par;
+ int idx;
+
+ for (ToplevelBlock t = this; t != null; t = t.Container) {
+ Parameters pars = t.Parameters;
+ par = pars.GetParameterByName (name, out idx);
+ if (par != null)
+ return new ParameterReference (pars, this, idx, name, loc);
+ }
+ return null;
+ }
+
+ //
+ // Whether the parameter named `name' is local to this block,
+ // or false, if the parameter belongs to an encompassing block.
+ //
+ public bool IsLocalParameter (string name)
+ {
+ return Parameters.GetParameterByName (name) != null;
+ }
+
+ //
+ // Whether the `name' is a parameter reference
+ //
+ public bool IsParameterReference (string name)
+ {
+ Parameter par;
+ int idx;
+
+ for (ToplevelBlock t = this; t != null; t = t.Container) {
+ if (t.IsLocalParameter (name))
+ return true;
+ }
+ return false;
+ }
+
public bool ResolveMeta (EmitContext ec, InternalParameters ip)
{
int errors = Report.Errors;
Expression e = (Expression) p.Second;
vi.VariableInfo.SetAssigned (ec);
- vi.ReadOnly = true;
+ vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed);
//
// The rules for the possible declarators are pretty wise,