**** Merged r40732-r40872 from MCS ****
authorMartin Baulig <martin@novell.com>
Tue, 22 Mar 2005 10:12:21 +0000 (10:12 -0000)
committerMartin Baulig <martin@novell.com>
Tue, 22 Mar 2005 10:12:21 +0000 (10:12 -0000)
svn path=/trunk/mcs/; revision=42082

mcs/gmcs/ChangeLog
mcs/gmcs/OPTIMIZE [new file with mode: 0644]
mcs/gmcs/attribute.cs
mcs/gmcs/class.cs
mcs/gmcs/constant.cs
mcs/gmcs/driver.cs
mcs/gmcs/ecore.cs
mcs/gmcs/expression.cs
mcs/gmcs/iterators.cs
mcs/gmcs/literal.cs
mcs/gmcs/rootcontext.cs

index bce9deb7b2a47cdc4c3abb805d8d1d0d76a09b26..8457cd836766cb61a9c5ff50db380ebab615af27 100644 (file)
@@ -1,3 +1,59 @@
+2005-02-18  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (EmitFieldInitializers): Don't emit field initializer
+       for default values when optimilization is on.
+       
+       * constant.cs (Constant.IsDefaultValue): New property.
+       
+       * driver.cs: Add /optimize handling.
+       
+       * constant.cs,
+       * ecore.cs,
+       * literal.cs: Implement new IsDefaultValue property.
+       
+       * rootcontext.cs (Optimize): New field, holds /optimize option.
+
+2005-02-18  Raja R Harinath  <rharinath@novell.com>
+
+       Fix crasher in re-opened #72347.
+       * namespace.cs (Namespace.Lookup): Return null if
+       DeclSpace.DefineType returns null.
+
+       Fix #72678.
+       * expression.cs (Argument.Resolve): Handle a case of CS0120 here.
+
+2005-02-18  Raja R Harinath  <rharinath@novell.com>
+
+       Fix remainder of #63202.  Change semantics of DoResolveLValue: it
+       now returns null if it cannot resolve to an lvalue.
+       * ecore.cs (Expression.DoResolveLValue): Return 'null' by default.
+       (Expression.ResolveLValue): Emit CS0131 error if DoResolveLValue
+       returned null.  Remove check for SimpleName.
+       (EventExpr.DoResolveLValue): New.
+       * iterators.cs (Iterator.FieldExpression.DoResolveLValue): New.
+       * expression.cs (Argument.Error_LValueRequired): New.  Move CS1510
+       error from ...
+       (Argument.Resolve): ... here.  Use it.  Use DoResolveLValue to
+       avoid CS0131 error.
+       (Unary.ResolveOperator): Move CS0211 check ...
+       (Unary.DoResolve): ... here.  Use DoResolveLValue to avoid
+       CS0131 error.
+       (Unary.DoResolveLValue): Simplify.
+       (AddressOf.DoResolveLValue): New.
+       (ArrayAccess.DoResolveLValue): New.
+
+2005-02-16  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs (Attribute.Resolve): Add arguments casting for
+       when types doesn't match ctor arguments.
+
+2005-02-16  Raja R Harinath  <rharinath@novell.com>
+
+       Fix parts of #63202.
+       * expression.cs (UnaryMutator.ResolveOperator): Remove redundant
+       lookup of operator in base type.  Ensure that all checks happen
+       when the operator resolves to an "op_..." method.
+
 2005-02-15  Raja R Harinath  <rharinath@novell.com>
 
        Fix #71992.
diff --git a/mcs/gmcs/OPTIMIZE b/mcs/gmcs/OPTIMIZE
new file mode 100644 (file)
index 0000000..6fa1e31
--- /dev/null
@@ -0,0 +1,26 @@
+This document describes all code optimalizations performed by Mono C# compiler
+when optimalizations are enabled via /optimize+ option.
+
+Optimalizations:
+
+* Instance field initializer to default value
+---------------------------------------------
+
+Code to optimize:
+
+class C
+{
+    enum E
+    {
+       Test
+    }
+    
+    int i = 0;  // Field will not be redundantly assigned
+    int i2 = new int (); // This will be also completely optimized out
+    
+    E e = E.Test; // Even this will go out.
+    
+}
+
+
+
index 0451f60cb2b1c882cba36dc3f6a8a4dfac65c086..1e6a5e7137de37b6d05da6e358f8c85cbe364144 100644 (file)
@@ -572,6 +572,16 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
+                               object value = pos_values [j];
+                               if (value != null && a.Type != value.GetType () && a.Type.IsPrimitive) {
+                                       bool fail;
+                                       pos_values [j] = TypeManager.ChangeType (value, a.Type, out fail);
+                                       if (fail) {
+                                               // TODO: Can failed ?
+                                               throw new NotImplementedException ();
+                                       }
+                               }
+
                                if (j < last_real_param)
                                        continue;
                                
index 6027fe321f6e7e56c76e966cf4bf08f0f079ce55..568fe966540b13b7a4cb02e3f7b72e9a2108d128 100644 (file)
@@ -866,6 +866,14 @@ namespace Mono.CSharp {
                                if (a == null)
                                        return false;
 
+                               if (RootContext.Optimize) {
+                                       Constant c = e as Constant;
+                                       if (c != null) {
+                                               if (c.IsDefaultValue)
+                                                       continue;
+                                       }
+                               }
+
                                a.EmitStatement (ec);
                        }
 
index 73de93f06f273af931fca1d08ccc103eaea55966..576c18a3b8f468b31ce02459bcd0f851ae980653 100644 (file)
@@ -162,6 +162,10 @@ namespace Mono.CSharp {
                        return null;
                }
                
+               public abstract bool IsDefaultValue {
+                       get;
+               }
+
                public abstract bool IsNegative {
                        get;
                }
@@ -205,6 +209,12 @@ namespace Mono.CSharp {
                                ec.ig.Emit (OpCodes.Ldc_I4_0);
                }
                
+               public override bool IsDefaultValue {
+                       get {
+                               return !Value;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return false;
@@ -271,6 +281,12 @@ namespace Mono.CSharp {
                        return new IntConstant (Value);
                }
                
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return false;
@@ -366,6 +382,12 @@ namespace Mono.CSharp {
                        return new IntConstant (Value);
                }
                
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return false;
@@ -435,6 +457,12 @@ namespace Mono.CSharp {
                        return new IntConstant (Value);
                }
                
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return Value < 0;
@@ -500,6 +528,12 @@ namespace Mono.CSharp {
                {
                        return new IntConstant (Value);
                }
+
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
                
                public override bool IsZeroInteger {
                        get { return Value == 0; }
@@ -567,6 +601,12 @@ namespace Mono.CSharp {
                        return new IntConstant (Value);
                }
                
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return false;
@@ -695,6 +735,12 @@ namespace Mono.CSharp {
                {
                        return this;
                }
+
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
                
                public override bool IsNegative {
                        get {
@@ -762,6 +808,12 @@ namespace Mono.CSharp {
                        return null;
                }
                
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return false;
@@ -843,6 +895,12 @@ namespace Mono.CSharp {
                        return null;
                }
                
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return Value < 0;
@@ -911,6 +969,12 @@ namespace Mono.CSharp {
                        return null;
                }
                
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return false;
@@ -972,6 +1036,12 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return Value < 0;
@@ -1034,6 +1104,12 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return Value < 0;
@@ -1094,6 +1170,12 @@ namespace Mono.CSharp {
                        ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
                }
 
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == 0;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return Value < 0;
@@ -1130,6 +1212,12 @@ namespace Mono.CSharp {
                                ec.ig.Emit (OpCodes.Ldstr, Value);
                }
 
+               public override bool IsDefaultValue {
+                       get {
+                               return Value == null;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return false;
index 3d915575128ac0d0eb03816332aff8465d5b48d9..4d74fe1cddae5ed9814fb48b9de6ac95a1f6eb9c 100644 (file)
@@ -220,6 +220,7 @@ namespace Mono.CSharp
                                "   -noconfig[+|-]     Disables implicit references to assemblies\n" +
                                "   -nostdlib[+|-]     Does not load core libraries\n" +
                                "   -nowarn:W1[,W2]    Disables one or more warnings\n" + 
+                               "   -optimize[+|-]     Enables code optimalizations" + Environment.NewLine +
                                "   -out:FNAME         Specifies output file\n" +
                                "   -pkg:P1[,Pn]       References packages P1..Pn\n" + 
                                "   --expect-error X   Expect that error X will be encountered\n" +
@@ -950,7 +951,13 @@ namespace Mono.CSharp
 
                        case "/optimize":
                        case "/optimize+":
+                               RootContext.Optimize = true;
+                               return true;
+
                        case "/optimize-":
+                               RootContext.Optimize = false;
+                               return true;
+
                        case "/incremental":
                        case "/incremental+":
                        case "/incremental-":
index a0eba82f5500dfbf09e3cff7ffffac6d842b4f6e..baf528bffae03ddaec3782e7ac4c4bb39085d332 100644 (file)
@@ -299,7 +299,7 @@ namespace Mono.CSharp {
 
                public virtual Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
-                       return DoResolve (ec);
+                       return null;
                }
 
                //
@@ -451,16 +451,16 @@ namespace Mono.CSharp {
                /// </remarks>
                public Expression ResolveLValue (EmitContext ec, Expression right_side)
                {
+                       int errors = Report.Errors;
                        Expression e = DoResolveLValue (ec, right_side);
 
-                       if (e != null){
-                               if (e is SimpleName){
-                                       SimpleName s = (SimpleName) e;
-                                       MemberLookupFailed (ec, null, ec.ContainerType, s.Name,
-                                                           ec.DeclSpace.Name, loc);
-                                       return null;
-                               }
+                       if (e == null) {
+                               if (errors == Report.Errors)
+                                       Report.Error (131, Location, "The left-hand side of an assignment or mutating operation must be a variable, property or indexer");
+                               return null;
+                       }
 
+                       if (e != null){
                                if (e.eclass == ExprClass.Invalid)
                                        throw new Exception ("Expression " + e +
                                                             " ExprClass is Invalid after resolve");
@@ -1444,6 +1444,7 @@ namespace Mono.CSharp {
                public EmptyCast (Expression child, Type return_type)
                {
                        eclass = child.eclass;
+                       loc = child.Location;
                        type = return_type;
                        this.child = child;
                }
@@ -1499,6 +1500,12 @@ namespace Mono.CSharp {
                        child.Emit (ec);
                }
 
+               public override bool IsDefaultValue {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return false;
@@ -1635,7 +1642,13 @@ namespace Mono.CSharp {
                {
                        return Child.ConvertToInt ();
                }
-               
+
+               public override bool IsDefaultValue {
+                       get {
+                               return Child.IsDefaultValue;
+                       }
+               }
+
                public override bool IsZeroInteger {
                        get { return Child.IsZeroInteger; }
                }
@@ -3658,6 +3671,11 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       return DoResolve (ec);
+               }
+
                public override Expression DoResolve (EmitContext ec)
                {
                        if (instance_expr != null) {
index d395ac505f5b59b4efc81c15aee6379b760864c9..4a7f5f28b7edaf741f0467dbda5c051f4934ac2c 100644 (file)
@@ -416,11 +416,6 @@ namespace Mono.CSharp {
                                return this;
 
                        case Operator.AddressOf:
-                               if (Expr.eclass != ExprClass.Variable){
-                                       Error (211, "Cannot take the address of non-variables");
-                                       return null;
-                               }
-                               
                                if (!ec.InUnsafe) {
                                        UnsafeError (loc); 
                                        return null;
@@ -575,8 +570,14 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       if (Oper == Operator.AddressOf)
-                               Expr = Expr.ResolveLValue (ec, new EmptyExpression ());
+                       if (Oper == Operator.AddressOf) {
+                               Expr = Expr.DoResolveLValue (ec, new EmptyExpression ());
+
+                               if (Expr == null || Expr.eclass != ExprClass.Variable){
+                                       Error (211, "Cannot take the address of non-variables");
+                                       return null;
+                               }
+                       }
                        else
                                Expr = Expr.Resolve (ec);
                        
@@ -593,10 +594,8 @@ namespace Mono.CSharp {
                public override Expression DoResolveLValue (EmitContext ec, Expression right)
                {
                        if (Oper == Operator.Indirection)
-                               return base.DoResolveLValue (ec, right);
+                               return DoResolve (ec);
 
-                       Error (131, "The left-hand side of an assignment must be a " +
-                              "variable, property or indexer");
                        return null;
                }
 
@@ -725,6 +724,11 @@ namespace Mono.CSharp {
                        expr.Emit (ec);
                }
 
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       return DoResolve (ec);
+               }
+
                public override Expression DoResolve (EmitContext ec)
                {
                        //
@@ -854,16 +858,15 @@ namespace Mono.CSharp {
 
                        mg = MemberLookup (ec, expr_type, op_name, MemberTypes.Method, AllBindingFlags, loc);
 
-                       if (mg == null && expr_type.BaseType != null)
-                               mg = MemberLookup (ec, expr_type.BaseType, op_name,
-                                                  MemberTypes.Method, AllBindingFlags, loc);
-                       
                        if (mg != null) {
                                method = StaticCallExpr.MakeSimpleCall (
                                        ec, (MethodGroupExpr) mg, expr, loc);
 
                                type = method.Type;
-                               return this;
+                       } else if (!IsIncrementableNumber (expr_type)) {
+                               Error (187, "No such operator '" + OperName (mode) + "' defined for type '" +
+                                      TypeManager.CSharpName (expr_type) + "'");
+                                  return null;
                        }
 
                        //
@@ -874,35 +877,20 @@ namespace Mono.CSharp {
                        type = expr_type;
                        if (expr.eclass == ExprClass.Variable){
                                LocalVariableReference var = expr as LocalVariableReference;
-                               if ((var != null) && var.IsReadOnly)
+                               if ((var != null) && var.IsReadOnly) {
                                        Error (1604, "cannot assign to `" + var.Name + "' because it is readonly");
-                               if (IsIncrementableNumber (expr_type) ||
-                                   expr_type == TypeManager.decimal_type){
-                                       return this;
+                                       return null;
                                }
-                       } else if (expr.eclass == ExprClass.IndexerAccess){
-                               IndexerAccess ia = (IndexerAccess) expr;
-                               
-                               expr = ia.ResolveLValue (ec, this);
+                       } else if (expr.eclass == ExprClass.IndexerAccess || expr.eclass == ExprClass.PropertyAccess){
+                               expr = expr.ResolveLValue (ec, this);
                                if (expr == null)
                                        return null;
-
-                               return this;
-                       } else if (expr.eclass == ExprClass.PropertyAccess){
-                               PropertyExpr pe = (PropertyExpr) expr;
-
-                               if (pe.VerifyAssignable ())
-                                       return this;
-
-                               return null;
                        } else {
                                expr.Error_UnexpectedKind ("variable, indexer or property access", loc);
                                return null;
                        }
 
-                       Error (187, "No such operator '" + OperName (mode) + "' defined for type '" +
-                              TypeManager.CSharpName (expr_type) + "'");
-                       return null;
+                       return this;
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -4220,6 +4208,11 @@ namespace Mono.CSharp {
                        return true;
                }
                
+               void Error_LValueRequired (Location loc)
+               {
+                       Report.Error (1510, loc, "An lvalue is required as an argument to out or ref");
+               }
+
                public bool Resolve (EmitContext ec, Location loc)
                {
                        if (ArgType == AType.Ref) {
@@ -4237,15 +4230,46 @@ namespace Mono.CSharp {
                                                return false;
                                        }
                                }
-                               Expr = Expr.ResolveLValue (ec, Expr);
-                       } else if (ArgType == AType.Out)
-                               Expr = Expr.ResolveLValue (ec, EmptyExpression.Null);
+                               Expr = Expr.DoResolveLValue (ec, Expr);
+                               if (Expr == null)
+                                       Error_LValueRequired (loc);
+                       } else if (ArgType == AType.Out) {
+                               Expr = Expr.DoResolveLValue (ec, EmptyExpression.Null);
+                               if (Expr == null)
+                                       Error_LValueRequired (loc);
+                       }
                        else
                                Expr = Expr.Resolve (ec);
 
                        if (Expr == null)
                                return false;
 
+                       if (Expr is IMemberExpr) {
+                               IMemberExpr me = Expr as IMemberExpr;
+
+                               //
+                               // This can happen with the following code:
+                               //
+                               //   class X {}
+                               //   class Y {
+                               //     public Y (X x) {}
+                               //   }
+                               //   class Z : Y {
+                               //     X X;
+                               //     public Z () : base (X) {}
+                               //   }
+                               //
+                               // SimpleNameResolve is conservative about flagging the X as
+                               // an error since it has identical name and type.  However,
+                               // because there's no MemberAccess, that is not really justified.
+                               // It is still simpler to fix it here, rather than in SimpleNameResolve.
+                               //
+                               if (me.IsInstance && me.InstanceExpression == null) {
+                                       SimpleName.Error_ObjectRefRequired (ec, loc, me.Name);
+                                       return false;
+                               }
+                       }
+
                        if (ArgType == AType.Expression)
                                return true;
                        else {
@@ -4279,9 +4303,7 @@ namespace Mono.CSharp {
                                                "A property or indexer can not be passed as an out or ref " +
                                                "parameter");
                                } else {
-                                       Report.Error (
-                                               1510, loc,
-                                               "An lvalue is required as an argument to out or ref");
+                                       Error_LValueRequired (loc);
                                }
                                return false;
                        }
@@ -5021,17 +5043,6 @@ namespace Mono.CSharp {
 
                                                candidates [k++] = candidates [i];
 
-#if false
-                                               //
-                                               // Methods marked 'override' don't take part in 'applicable_type'
-                                               // computation.
-                                               //
-                                               if (!me.IsBase &&
-                                                   candidate.IsVirtual &&
-                                                   (candidate.Attributes & MethodAttributes.NewSlot) == 0)
-                                                       continue;
-#endif
-
                                                if (next_applicable_type == null ||
                                                    IsAncestralType (next_applicable_type, decl_type))
                                                        next_applicable_type = decl_type;
@@ -8052,6 +8063,11 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       return DoResolve (ec);
+               }
+
                public override Expression DoResolve (EmitContext ec)
                {
 #if false
index 85cd202458601957feeb19acffd112fa21a28714..56bb333c94bec63521c23aa16b249520298a98c2 100644 (file)
@@ -804,6 +804,11 @@ namespace Mono.CSharp {
                                this.field = field;
                        }
 
+                       public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+                       {
+                               return DoResolve (ec);
+                       }
+
                        public override Expression DoResolve (EmitContext ec)
                        {
                                FieldExpr fexpr = new FieldExpr (field.FieldBuilder, loc);
index 0a97d502b5046af510de45853feb4e18fba29e99..1d7396536c633b41126120195e4daa076cd97620 100644 (file)
@@ -79,7 +79,13 @@ namespace Mono.CSharp {
                {
                        ec.ig.Emit (OpCodes.Ldnull);
                }
-               
+
+               public override bool IsDefaultValue {
+                       get {
+                               return true;
+                       }
+               }
+
                public override bool IsNegative {
                        get {
                                return false;
index dffeaeda752431eefb44d53b2282f3e9887bda9f..3e79b457aa602170bd62349baaee892530a75467 100644 (file)
@@ -71,6 +71,11 @@ namespace Mono.CSharp {
 
                public static bool VerifyClsCompliance = true;
 
+               /// <summary>
+               /// Holds /optimize option
+               /// </summary>
+               public static bool Optimize = true;
+
                public static LanguageVersion Version = LanguageVersion.Default;
 
                //