oops.
[mono.git] / mcs / mcs / statement.cs
old mode 100755 (executable)
new mode 100644 (file)
index 45fe082..e050e8f
@@ -3,7 +3,7 @@
 //
 // 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.
@@ -46,16 +46,14 @@ namespace Mono.CSharp {
                        // 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)
@@ -148,6 +146,11 @@ namespace Mono.CSharp {
                                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
                        //
@@ -672,6 +675,7 @@ namespace Mono.CSharp {
                bool defined;
                bool referenced;
                Label label;
+               ILGenerator ig;
 
                FlowBranching.UsageVector vectors;
                
@@ -684,6 +688,7 @@ namespace Mono.CSharp {
                {
                        if (defined)
                                return label;
+                       ig = ec.ig;
                        label = ec.ig.DefineLabel ();
                        defined = true;
 
@@ -720,6 +725,10 @@ namespace Mono.CSharp {
 
                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);
                }
@@ -822,7 +831,6 @@ namespace Mono.CSharp {
 
                public override bool Resolve (EmitContext ec)
                {
-                       bool in_catch = ec.CurrentBranching.InCatch ();
                        ec.CurrentBranching.CurrentUsageVector.Throw ();
 
                        if (expr != null){
@@ -833,7 +841,7 @@ namespace Mono.CSharp {
                                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;
                                }
@@ -841,20 +849,25 @@ namespace Mono.CSharp {
                                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;
                }
                        
@@ -1420,12 +1433,12 @@ namespace Mono.CSharp {
                // </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;
                        }
                }
 
@@ -1747,8 +1760,6 @@ namespace Mono.CSharp {
                /// </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
@@ -2117,8 +2128,6 @@ namespace Mono.CSharp {
 
                static int did = 0;
                
-               int my_id = did++;
-
                        
                public void RegisterCaptureContext (CaptureContext cc)
                {
@@ -2347,12 +2356,12 @@ namespace Mono.CSharp {
 
                        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,
@@ -2375,13 +2384,26 @@ namespace Mono.CSharp {
                                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;
                }
@@ -3871,7 +3893,7 @@ namespace Mono.CSharp {
                        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 ();
 
@@ -4072,6 +4094,11 @@ namespace Mono.CSharp {
                        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;
@@ -4273,7 +4300,6 @@ namespace Mono.CSharp {
                                        return false;
                        }
                        ForeachHelperMethods hm = (ForeachHelperMethods) criteria;
-                       EmitContext ec = hm.ec;
 
                        // Check whether GetEnumerator is public
                        if ((mi.Attributes & MethodAttributes.Public) != MethodAttributes.Public)
@@ -4490,7 +4516,8 @@ namespace Mono.CSharp {
                        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){
@@ -4587,7 +4614,7 @@ namespace Mono.CSharp {
                                ig.MarkLabel (loop);
 
                                if (ec.InIterator)
-                                       ec.EmitThis ();
+                                       ig.Emit (OpCodes.Ldarg_0);
                                
                                copy.EmitThis (ig);
                                copy.EmitLoad (ig);
@@ -4656,7 +4683,8 @@ namespace Mono.CSharp {
                                }
 
                                if (ec.InIterator)
-                                       ec.EmitThis ();
+                                       ig.Emit (OpCodes.Ldarg_0);
+                               
                                copy.EmitThis (ig);
                                copy.EmitLoad (ig);
                                for (dim = 0; dim < rank; dim++){