//
// Author:
// Miguel de Icaza (miguel@ximian.com)
-// Martin Baulig (martin@gnome.org)
+// Martin Baulig (martin@ximian.com)
//
// (C) 2001, 2002, 2003 Ximian, Inc.
// (C) 2003, 2004 Novell, Inc.
// in unreachable code, for instance.
//
+ if (warn && (RootContext.WarningLevel >= 2))
+ Report.Warning (162, loc, "Unreachable code detected");
+
ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
bool ok = Resolve (ec);
ec.KillFlowBranching ();
- if (!ok)
- return false;
-
- if (warn && (RootContext.WarningLevel >= 2))
- Report.Warning (162, loc, "Unreachable code detected");
- return true;
+ return ok;
}
protected void CheckObsolete (Type type)
return false;
}
+ Assign ass = expr as Assign;
+ if (ass != null && ass.Source is Constant) {
+ Report.Warning (665, 3, loc, "Assignment in conditional expression is always constant; did you mean to use == instead of = ?");
+ }
+
//
// Dead code elimination
//
bool defined;
bool referenced;
Label label;
+ ILGenerator ig;
FlowBranching.UsageVector vectors;
{
if (defined)
return label;
+ ig = ec.ig;
label = ec.ig.DefineLabel ();
defined = true;
protected override void DoEmit (EmitContext ec)
{
+ if (ig != null && ig != ec.ig) {
+ Report.Error (1632, "Control cannot leave body of anonymous method");
+ return;
+ }
LabelTarget (ec);
ec.ig.MarkLabel (label);
}
public override bool Resolve (EmitContext ec)
{
- bool in_catch = ec.CurrentBranching.InCatch ();
ec.CurrentBranching.CurrentUsageVector.Throw ();
if (expr != null){
ExprClass eclass = expr.eclass;
if (!(eclass == ExprClass.Variable || eclass == ExprClass.PropertyAccess ||
- eclass == ExprClass.Value || eclass == ExprClass.IndexerAccess)) {
+ eclass == ExprClass.Value || eclass == ExprClass.IndexerAccess)) {
expr.Error_UnexpectedKind ("value, variable, property or indexer access ", loc);
return false;
}
Type t = expr.Type;
if ((t != TypeManager.exception_type) &&
- !t.IsSubclassOf (TypeManager.exception_type) &&
- !(expr is NullLiteral)) {
+ !t.IsSubclassOf (TypeManager.exception_type) &&
+ !(expr is NullLiteral)) {
Error (155,
- "The type caught or thrown must be derived " +
- "from System.Exception");
+ "The type caught or thrown must be derived " +
+ "from System.Exception");
return false;
}
- } else if (!in_catch) {
- Error (156,
- "A throw statement with no argument is only " +
- "allowed in a catch clause");
+ return true;
+ }
+
+ if (ec.CurrentBranching.InFinally (true)) {
+ Error (724, "A throw statement with no argument is only allowed in a catch clause nested inside of the innermost catch clause");
return false;
}
+ if (!ec.CurrentBranching.InCatch ()) {
+ Error (156, "A throw statement with no argument is only allowed in a catch clause");
+ return false;
+ }
return true;
}
ReadOnly = 2,
Pinned = 4,
IsThis = 8,
- Captured = 16
+ Captured = 16,
+ AddressTaken = 32
}
Flags flags;
}
}
+ public bool AddressTaken {
+ get {
+ return (flags & Flags.AddressTaken) != 0;
+ }
+
+ set {
+ flags |= Flags.AddressTaken;
+ }
+ }
+
public override string ToString ()
{
return String.Format ("LocalInfo ({0},{1},{2},{3})",
// </summary>
public LocalInfo ThisVariable {
get {
- if (this_variable != null)
- return this_variable;
- else if (Parent != null)
- return Parent.ThisVariable;
- else
- return null;
+ for (Block b = this; b != null; b = b.Parent) {
+ if (b.this_variable != null)
+ return b.this_variable;
+ }
+
+ return null;
}
}
if (child_variable_names == null)
child_variable_names = new Hashtable ();
- if (!child_variable_names.Contains (name))
- child_variable_names.Add (name, true);
+ child_variable_names [name] = null;
}
// <summary>
/// </remarks>
public void ResolveMeta (ToplevelBlock toplevel, EmitContext ec, InternalParameters ip)
{
- ILGenerator ig = ec.ig;
-
bool old_unsafe = ec.InUnsafe;
// If some parent block was unsafe, we remain unsafe even if this block
static int did = 0;
- int my_id = did++;
-
public void RegisterCaptureContext (CaptureContext cc)
{
if (allowed_types == null){
allowed_types = new Type [] {
+ TypeManager.int32_type,
+ TypeManager.uint32_type,
TypeManager.sbyte_type,
TypeManager.byte_type,
TypeManager.short_type,
TypeManager.ushort_type,
- TypeManager.int32_type,
- TypeManager.uint32_type,
TypeManager.int64_type,
TypeManager.uint64_type,
TypeManager.char_type,
if (e == null)
continue;
+ //
+ // Ignore over-worked ImplicitUserConversions that do
+ // an implicit conversion in addition to the user conversion.
+ //
+ if (e is UserCast){
+ UserCast ue = e as UserCast;
+
+ if (ue.Source != Expr)
+ e = null;
+ }
+
if (converted != null){
- Report.Error (-12, loc, "More than one conversion to an integral " +
- " type exists for type `" +
- TypeManager.CSharpName (Expr.Type)+"'");
+ Report.ExtraInformation (
+ loc,
+ String.Format ("reason: more than one conversion to an integral type exist for type {0}",
+ TypeManager.CSharpName (Expr.Type)));
return null;
- } else
+ } else {
converted = e;
+ }
}
return converted;
}
ILGenerator ig = ec.ig;
int i = assign.Length;
- foreach (DictionaryEntry e in var_list){
+ for (int ii = 0; ii < var_list.Count; ++ii){
Expression var = resolved_vars [--i];
Label skip = ig.DefineLabel ();
void EmitExpressionFinally (EmitContext ec)
{
ILGenerator ig = ec.ig;
- Label skip = ig.DefineLabel ();
- ig.Emit (OpCodes.Ldloc, local_copy);
- ig.Emit (OpCodes.Brfalse, skip);
- ig.Emit (OpCodes.Ldloc, local_copy);
- ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
- ig.MarkLabel (skip);
+ if (!local_copy.LocalType.IsValueType) {
+ Label skip = ig.DefineLabel ();
+ ig.Emit (OpCodes.Ldloc, local_copy);
+ ig.Emit (OpCodes.Brfalse, skip);
+ ig.Emit (OpCodes.Ldloc, local_copy);
+ ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+ ig.MarkLabel (skip);
+ } else {
+ Expression ml = Expression.MemberLookup(ec, TypeManager.idisposable_type, local_copy.LocalType, "Dispose", Mono.CSharp.Location.Null);
+
+ if (!(ml is MethodGroupExpr)) {
+ ig.Emit (OpCodes.Ldloc, local_copy);
+ ig.Emit (OpCodes.Box, local_copy.LocalType);
+ ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+ } else {
+ MethodInfo mi = null;
+
+ foreach (MethodInfo mk in ((MethodGroupExpr) ml).Methods) {
+ if (TypeManager.GetArgumentTypes (mk).Length == 0) {
+ mi = mk;
+ break;
+ }
+ }
+
+ if (mi == null) {
+ Report.Error(-100, Mono.CSharp.Location.Null, "Internal error: No Dispose method which takes 0 parameters.");
+ return;
+ }
+
+ ig.Emit (OpCodes.Ldloca, local_copy);
+ ig.Emit (OpCodes.Call, mi);
+ }
+ }
}
public override bool Resolve (EmitContext ec)
if (expr == null)
return false;
+ if (expr is NullLiteral) {
+ Report.Error (186, expr.Location, "Use of null is not valid in this context");
+ return false;
+ }
+
TypeExpr texpr = type.ResolveAsTypeTerminal (ec, false);
if (texpr == null)
return false;
if (hm == null){
error1579 (expr.Type);
return false;
- }
+ }
+ // When ProbeCollection reported error
+ if (hm.move_next == null)
+ return false;
+
array_type = expr.Type;
element_type = hm.element_type;
public Type element_type;
public Type enumerator_type;
public bool is_disposable;
+ public readonly Location Location;
- public ForeachHelperMethods (EmitContext ec)
+ public ForeachHelperMethods (EmitContext ec, Location loc)
{
this.ec = ec;
+ this.Location = loc;
this.element_type = TypeManager.object_type;
this.enumerator_type = TypeManager.ienumerator_type;
this.is_disposable = true;
return false;
}
ForeachHelperMethods hm = (ForeachHelperMethods) criteria;
- EmitContext ec = hm.ec;
// Check whether GetEnumerator is public
if ((mi.Attributes & MethodAttributes.Public) != MethodAttributes.Public)
} else {
+ if (return_type.IsPointer || return_type.IsArray) {
+ Report.SymbolRelatedToPreviousError (mi);
+ Type t = return_type.GetElementType ();
+ Report.SymbolRelatedToPreviousError (t);
+ Report.Error (202, hm.Location, "foreach requires that the return type '{0}' of '{1}' must have a suitable public MoveNext method and public Current property",
+ TypeManager.CSharpName (return_type), TypeManager.GetFullNameSignature (m));
+ hm.get_enumerator = mi;
+ return false;
+ }
+
//
// Ok, so they dont return an IEnumerable, we will have to
// find if they support the GetEnumerator pattern.
//
ForeachHelperMethods ProbeCollectionType (EmitContext ec, Type t)
{
- ForeachHelperMethods hm = new ForeachHelperMethods (ec);
+ ForeachHelperMethods hm = new ForeachHelperMethods (ec, loc);
for (Type tt = t; tt != null && tt != TypeManager.object_type;){
if (TryType (tt, hm))
ig.Emit (OpCodes.Brfalse, end_try);
if (ec.InIterator)
- enumerator.EmitThis (ig);
+ ig.Emit (OpCodes.Ldarg_0);
+
enumerator.EmitCall (ig, hm.get_current);
if (ec.InIterator){
ig.MarkLabel (loop);
if (ec.InIterator)
- ec.EmitThis ();
+ ig.Emit (OpCodes.Ldarg_0);
copy.EmitThis (ig);
copy.EmitLoad (ig);
}
if (ec.InIterator)
- ec.EmitThis ();
+ ig.Emit (OpCodes.Ldarg_0);
+
copy.EmitThis (ig);
copy.EmitLoad (ig);
for (dim = 0; dim < rank; dim++){