Merge pull request #418 from LogosBible/bug6403
[mono.git] / mcs / mcs / statement.cs
index 8588c373427814f47cbc8d88f9a90a72aef3138f..e6cdf85bd34ab17c64b4fa00ffc5c011b899948f 100644 (file)
@@ -281,11 +281,16 @@ namespace Mono.CSharp {
                public Expression expr;
                public Statement  EmbeddedStatement;
 
-               public Do (Statement statement, BooleanExpression bool_expr, Location l)
+               public Do (Statement statement, BooleanExpression bool_expr, Location doLocation, Location whileLocation)
                {
                        expr = bool_expr;
                        EmbeddedStatement = statement;
-                       loc = l;
+                       loc = doLocation;
+                       WhileLocation = whileLocation;
+               }
+
+               public Location WhileLocation {
+                       get; private set;
                }
 
                public override bool Resolve (BlockContext ec)
@@ -332,7 +337,7 @@ namespace Mono.CSharp {
                        ec.MarkLabel (ec.LoopBegin);
 
                        // Mark start of while condition
-                       ec.Mark (expr.Location);
+                       ec.Mark (WhileLocation);
 
                        //
                        // Dead code elimination
@@ -461,7 +466,7 @@ namespace Mono.CSharp {
                        
                                ec.MarkLabel (ec.LoopBegin);
 
-                               ec.Mark (expr.Location);
+                               ec.Mark (loc);
                                expr.EmitBranchable (ec, while_loop, true);
                                
                                ec.MarkLabel (ec.LoopEnd);
@@ -878,7 +883,6 @@ namespace Mono.CSharp {
                                                        return true;
                                                }
 
-                                               // TODO: Better error message
                                                if (async_type.Kind == MemberKind.Void) {
                                                        ec.Report.Error (127, loc,
                                                                "`{0}': A return keyword must not be followed by any expression when method returns void",
@@ -909,6 +913,15 @@ namespace Mono.CSharp {
                                                }
                                        }
                                } else {
+                                       // Same error code as .NET but better error message
+                                       if (block_return_type.Kind == MemberKind.Void) {
+                                               ec.Report.Error (127, loc,
+                                                       "`{0}': A return keyword must not be followed by any expression when delegate returns void",
+                                                       am.GetSignatureForError ());
+
+                                               return false;
+                                       }
+
                                        var l = am as AnonymousMethodBody;
                                        if (l != null && l.ReturnTypeInference != null && expr != null) {
                                                l.ReturnTypeInference.AddCommonTypeBound (expr.Type);
@@ -1620,8 +1633,10 @@ namespace Mono.CSharp {
                        if (declarators != null) {
                                foreach (var d in declarators) {
                                        d.Variable.CreateBuilder (ec);
-                                       if (d.Initializer != null)
+                                       if (d.Initializer != null) {
+                                               ec.Mark (d.Variable.Location);
                                                ((ExpressionStatement) d.Initializer).EmitStatement (ec);
+                                       }
                                }
                        }
                }
@@ -2820,7 +2835,7 @@ namespace Mono.CSharp {
                        // Overwrite original for comparison purposes when linking cross references
                        // between anonymous methods
                        //
-                       Original = source;
+                       Original = source.Original;
                }
 
                #region Properties
@@ -4236,10 +4251,10 @@ namespace Mono.CSharp {
 
                                Expression cond = null;
                                for (int ci = 0; ci < s.Labels.Count; ++ci) {
-                                       var e = new Binary (Binary.Operator.Equality, value, s.Labels[ci].Converted, loc);
+                                       var e = new Binary (Binary.Operator.Equality, value, s.Labels[ci].Converted);
 
                                        if (ci > 0) {
-                                               cond = new Binary (Binary.Operator.LogicalOr, cond, e, loc);
+                                               cond = new Binary (Binary.Operator.LogicalOr, cond, e);
                                        } else {
                                                cond = e;
                                        }
@@ -5129,8 +5144,8 @@ namespace Mono.CSharp {
                                        // fixed (T* e_ptr = (e == null || e.Length == 0) ? null : converted [0])
                                        //
                                        converted = new Conditional (new BooleanExpression (new Binary (Binary.Operator.LogicalOr,
-                                               new Binary (Binary.Operator.Equality, initializer, new NullLiteral (loc), loc),
-                                               new Binary (Binary.Operator.Equality, new MemberAccess (initializer, "Length"), new IntConstant (bc.BuiltinTypes, 0, loc), loc), loc)),
+                                               new Binary (Binary.Operator.Equality, initializer, new NullLiteral (loc)),
+                                               new Binary (Binary.Operator.Equality, new MemberAccess (initializer, "Length"), new IntConstant (bc.BuiltinTypes, 0, loc)))),
                                                        new NullLiteral (loc),
                                                        converted, loc);
 
@@ -5688,7 +5703,7 @@ namespace Mono.CSharp {
 
                                // Add conditional call when disposing possible null variable
                                if (!type.IsStruct || type.IsNullableType)
-                                       dispose = new If (new Binary (Binary.Operator.Inequality, lvr, new NullLiteral (loc), loc), dispose, dispose.loc);
+                                       dispose = new If (new Binary (Binary.Operator.Inequality, lvr, new NullLiteral (loc)), dispose, dispose.loc);
 
                                return dispose;
                        }
@@ -5702,7 +5717,7 @@ namespace Mono.CSharp {
                        {
                                for (int i = declarators.Count - 1; i >= 0; --i) {
                                        var d = declarators [i];
-                                       var vd = new VariableDeclaration (d.Variable, type_expr.Location);
+                                       var vd = new VariableDeclaration (d.Variable, d.Variable.Location);
                                        vd.Initializer = d.Initializer;
                                        vd.IsNested = true;
                                        vd.dispose_call = CreateDisposeCall (bc, d.Variable);
@@ -5938,7 +5953,7 @@ namespace Mono.CSharp {
                                if (variable_ref == null)
                                        return false;
 
-                               for_each.body.AddScopeStatement (new StatementExpression (new CompilerAssign (variable_ref, access, Location.Null), for_each.variable.Location));
+                               for_each.body.AddScopeStatement (new StatementExpression (new CompilerAssign (variable_ref, access, Location.Null), for_each.type.Location));
 
                                bool ok = true;
 
@@ -6034,7 +6049,7 @@ namespace Mono.CSharp {
                                        var idisaposable_test = new Binary (Binary.Operator.Inequality, new CompilerAssign (
                                                dispose_variable.CreateReferenceExpression (bc, loc),
                                                new As (lv.CreateReferenceExpression (bc, loc), new TypeExpression (dispose_variable.Type, loc), loc),
-                                               loc), new NullLiteral (loc), loc);
+                                               loc), new NullLiteral (loc));
 
                                        var m = bc.Module.PredefinedMembers.IDisposableDispose.Resolve (loc);
 
@@ -6249,7 +6264,7 @@ namespace Mono.CSharp {
                                if (variable_ref == null)
                                        return false;
 
-                               for_each.body.AddScopeStatement (new StatementExpression (new CompilerAssign (variable_ref, current_pe, Location.Null), variable.Location));
+                               for_each.body.AddScopeStatement (new StatementExpression (new CompilerAssign (variable_ref, current_pe, Location.Null), for_each.type.Location));
 
                                var init = new Invocation (get_enumerator_mg, null);