2004-11-02 Ben Maurer <bmaurer@ximian.com>
[mono.git] / mcs / mcs / expression.cs
index 7a743fb03f80cd8aa004e172b89d30f57d69d6c7..af1be64d86bcf0604f3389d24c92f1a71dbcae81 100755 (executable)
@@ -2138,6 +2138,10 @@ namespace Mono.CSharp {
                                    (other == TypeManager.int32_type) ||
                                    (other == TypeManager.int64_type))
                                        Error_OperatorAmbiguous (loc, oper, l, r);
+                               else {
+                                       left = ForceConversion (ec, left, TypeManager.uint64_type);
+                                       right = ForceConversion (ec, right, TypeManager.uint64_type);
+                               }
                                type = TypeManager.uint64_type;
                        } else if (IsOfType (ec, l, r, TypeManager.int64_type, check_user_conv)){
                                //
@@ -2305,14 +2309,12 @@ namespace Mono.CSharp {
                        Type l = left.Type;
                        Type r = right.Type;
 
-                       bool overload_failed = false;
-
                        //
                        // Special cases: string comapred to null
                        //
                        if (oper == Operator.Equality || oper == Operator.Inequality){
-                               if ((l == TypeManager.string_type && (right is NullLiteral)) ||
-                                   (r == TypeManager.string_type && (left is NullLiteral))){
+                               if ((!TypeManager.IsValueType (l) && (right is NullLiteral)) ||
+                                   (!TypeManager.IsValueType (r) && (left is NullLiteral))) {
                                        Type = TypeManager.bool_type;
                                        
                                        return this;
@@ -2357,8 +2359,6 @@ namespace Mono.CSharp {
                                                MethodInfo mi = (MethodInfo) method;
                                                
                                                return new BinaryMethod (mi.ReturnType, method, args);
-                                       } else {
-                                               overload_failed = true;
                                        }
                                }
                        }
@@ -2537,16 +2537,16 @@ namespace Mono.CSharp {
                                                if (r == l)
                                                        return new PointerArithmetic (
                                                                false, left, right, TypeManager.int64_type,
-                                                               loc);
+                                                               loc).Resolve (ec);
                                        } else {
                                                Expression t = Make32or64 (ec, right);
                                                if (t != null)
-                                                       return new PointerArithmetic (oper == Operator.Addition, left, t, l, loc);
+                                                       return new PointerArithmetic (oper == Operator.Addition, left, t, l, loc).Resolve (ec);
                                        }
                                } else if (r.IsPointer && oper == Operator.Addition){
                                        Expression t = Make32or64 (ec, left);
                                        if (t != null)
-                                               return new PointerArithmetic (true, right, t, r, loc);
+                                               return new PointerArithmetic (true, right, t, r, loc).Resolve (ec);
                                }
                        }
                        
@@ -2683,14 +2683,6 @@ namespace Mono.CSharp {
                                }
                        }
                        
-                       //
-                       // We are dealing with numbers
-                       //
-                       if (overload_failed){
-                               Error_OperatorCannotBeApplied ();
-                               return null;
-                       }
-
                        //
                        // This will leave left or right set to null if there is an error
                        //
@@ -3154,7 +3146,11 @@ namespace Mono.CSharp {
        public class StringConcat : Expression {
                ArrayList operands;
                bool invalid = false;
-               
+               bool emit_conv_done = false;
+               //
+               // Are we also concating objects?
+               //
+               bool is_strings_only = true;
                
                public StringConcat (EmitContext ec, Location loc, Expression left, Expression right)
                {
@@ -3208,30 +3204,30 @@ namespace Mono.CSharp {
                {
                        MethodInfo concat_method = null;
                        
-                       //
-                       // Are we also concating objects?
-                       //
-                       bool is_strings_only = true;
-                       
                        //
                        // Do conversion to arguments; check for strings only
                        //
-                       for (int i = 0; i < operands.Count; i ++) {
-                               Expression e = (Expression) operands [i];
-                               is_strings_only &= e.Type == TypeManager.string_type;
-                       }
                        
-                       for (int i = 0; i < operands.Count; i ++) {
-                               Expression e = (Expression) operands [i];
+                       // This can get called multiple times, so we have to deal with that.
+                       if (!emit_conv_done) {
+                               emit_conv_done = true;
+                               for (int i = 0; i < operands.Count; i ++) {
+                                       Expression e = (Expression) operands [i];
+                                       is_strings_only &= e.Type == TypeManager.string_type;
+                               }
                                
-                               if (! is_strings_only && e.Type == TypeManager.string_type) {
-                                       // need to make sure this is an object, because the EmitParams
-                                       // method might look at the type of this expression, see it is a
-                                       // string and emit a string [] when we want an object [];
+                               for (int i = 0; i < operands.Count; i ++) {
+                                       Expression e = (Expression) operands [i];
                                        
-                                       e = Convert.ImplicitConversion (ec, e, TypeManager.object_type, loc);
+                                       if (! is_strings_only && e.Type == TypeManager.string_type) {
+                                               // need to make sure this is an object, because the EmitParams
+                                               // method might look at the type of this expression, see it is a
+                                               // string and emit a string [] when we want an object [];
+                                               
+                                               e = new EmptyCast (e, TypeManager.object_type);
+                                       }
+                                       operands [i] = new Argument (e, Argument.AType.Expression);
                                }
-                               operands [i] = new Argument (e, Argument.AType.Expression);
                        }
                        
                        //
@@ -3418,7 +3414,6 @@ namespace Mono.CSharp {
                public PointerArithmetic (bool is_addition, Expression l, Expression r, Type t, Location loc)
                {
                        type = t;
-                       eclass = ExprClass.Variable;
                        this.loc = loc;
                        left = l;
                        right = r;
@@ -3427,9 +3422,13 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       //
-                       // We are born fully resolved
-                       //
+                       eclass = ExprClass.Variable;
+                       
+                       if (left.Type == TypeManager.void_ptr_type) {
+                               Error (242, "The operation in question is undefined on void pointers");
+                               return null;
+                       }
+                       
                        return this;
                }
 
@@ -3437,7 +3436,8 @@ namespace Mono.CSharp {
                {
                        Type op_type = left.Type;
                        ILGenerator ig = ec.ig;
-                       int size = GetTypeSize (TypeManager.GetElementType (op_type));
+                       Type element = TypeManager.GetElementType (op_type);
+                       int size = GetTypeSize (element);
                        Type rtype = right.Type;
                        
                        if (rtype.IsPointer){
@@ -3450,7 +3450,7 @@ namespace Mono.CSharp {
 
                                if (size != 1){
                                        if (size == 0)
-                                               ig.Emit (OpCodes.Sizeof, op_type);
+                                               ig.Emit (OpCodes.Sizeof, element);
                                        else 
                                                IntLiteral.EmitInt (ig, size);
                                        ig.Emit (OpCodes.Div);
@@ -3465,7 +3465,7 @@ namespace Mono.CSharp {
                                right.Emit (ec);
                                if (size != 1){
                                        if (size == 0)
-                                               ig.Emit (OpCodes.Sizeof, op_type);
+                                               ig.Emit (OpCodes.Sizeof, element);
                                        else 
                                                IntLiteral.EmitInt (ig, size);
                                        if (rtype == TypeManager.int64_type)
@@ -3473,8 +3473,11 @@ namespace Mono.CSharp {
                                        else if (rtype == TypeManager.uint64_type)
                                                ig.Emit (OpCodes.Conv_U8);
                                        ig.Emit (OpCodes.Mul);
-                                       ig.Emit (OpCodes.Conv_I);
                                }
+                               
+                               if (rtype == TypeManager.int64_type || rtype == TypeManager.uint64_type)
+                                       ig.Emit (OpCodes.Conv_I);
+                               
                                if (is_add)
                                        ig.Emit (OpCodes.Add);
                                else
@@ -3668,7 +3671,7 @@ namespace Mono.CSharp {
                        if (e != null) {
                                local_info.Used = true;
                                eclass = ExprClass.Value;
-                               return e;
+                               return e.Resolve (ec);
                        }
 
                        VariableInfo variable_info = local_info.VariableInfo; 
@@ -3969,7 +3972,8 @@ namespace Mono.CSharp {
                public enum AType : byte {
                        Expression,
                        Ref,
-                       Out
+                       Out,
+                       ArgList
                };
 
                public readonly AType ArgType;
@@ -4006,6 +4010,9 @@ namespace Mono.CSharp {
 
                public static string FullDesc (Argument a)
                {
+                       if (a.ArgType == AType.ArgList)
+                               return "__arglist";
+
                        return (a.ArgType == AType.Ref ? "ref " :
                                (a.ArgType == AType.Out ? "out " : "")) +
                                TypeManager.CSharpName (a.Expr.Type);
@@ -4167,8 +4174,7 @@ namespace Mono.CSharp {
 
                                return (ParameterData) ip;
                        } else {
-                               ParameterInfo [] pi = mb.GetParameters ();
-                               ReflectionParameters rp = new ReflectionParameters (pi);
+                               ReflectionParameters rp = new ReflectionParameters (mb);
                                method_parameter_cache [mb] = rp;
 
                                return (ParameterData) rp;
@@ -4230,85 +4236,6 @@ namespace Mono.CSharp {
                        if (argument_type == q)
                                return 0;
 
-                       //
-                       // Now probe whether an implicit constant expression conversion
-                       // can be used.
-                       //
-                       // An implicit constant expression conversion permits the following
-                       // conversions:
-                       //
-                       //    * A constant-expression of type `int' can be converted to type
-                       //      sbyte, byute, short, ushort, uint, ulong provided the value of
-                       //      of the expression is withing the range of the destination type.
-                       //
-                       //    * A constant-expression of type long can be converted to type
-                       //      ulong, provided the value of the constant expression is not negative
-                       //
-                       // FIXME: Note that this assumes that constant folding has
-                       // taken place.  We dont do constant folding yet.
-                       //
-
-                       if (argument_expr is IntConstant){
-                               IntConstant ei = (IntConstant) argument_expr;
-                               int value = ei.Value;
-
-                               if (p == TypeManager.sbyte_type){
-                                       if (value >= SByte.MinValue && value <= SByte.MaxValue)
-                                               return 1;
-                               } else if (p == TypeManager.byte_type){
-                                       if (q == TypeManager.sbyte_type &&
-                                           value >= SByte.MinValue && value <= SByte.MaxValue)
-                                               return 0;
-                                       else if (Byte.MinValue >= 0 && value <= Byte.MaxValue)
-                                               return 1;
-                               } else if (p == TypeManager.short_type){
-                                       if (value >= Int16.MinValue && value <= Int16.MaxValue)
-                                               return 1;
-                               } else if (p == TypeManager.ushort_type){
-                                       if (q == TypeManager.short_type &&
-                                           value >= Int16.MinValue && value <= Int16.MaxValue)
-                                               return 0;
-                                       else if (value >= UInt16.MinValue && value <= UInt16.MaxValue)
-                                               return 1;
-                               } else if (p == TypeManager.int32_type){
-                                       if (value >= Int32.MinValue && value <= Int32.MaxValue)
-                                               return 1;
-                               } else if (p == TypeManager.uint32_type){
-                                       //
-                                       // we can optimize this case: a positive int32
-                                       // always fits on a uint32
-                                       //
-                                       if (value >= 0)
-                                               return 1;
-                               } else if (p == TypeManager.uint64_type){
-                                       //
-                                       // we can optimize this case: a positive int32
-                                       // always fits on a uint64
-                                       //
-
-                                        //
-                                        // This special case is needed because csc behaves like this.
-                                        // int -> uint is better than int -> ulong!
-                                        //
-                                        if (q == TypeManager.uint32_type)
-                                                return 0;
-                                        
-                                       if (q == TypeManager.int64_type)
-                                               return 0;
-                                       else if (value >= 0)
-                                               return 1;
-                               } else if (p == TypeManager.int64_type){
-                                       return 1;
-                               }
-                       } else if (argument_type == TypeManager.int64_type && argument_expr is LongConstant){
-                               LongConstant lc = (LongConstant) argument_expr;
-                               
-                               if (p == TypeManager.uint64_type){
-                                       if (lc.Value > 0)
-                                               return 1;
-                               }
-                       }
-
                        if (q == null) {
                                Expression tmp = Convert.ImplicitConversion (ec, argument_expr, p, loc);
                                
@@ -4395,7 +4322,8 @@ namespace Mono.CSharp {
                        if (cand_count == 0 && argument_count == 0)
                                return best == null || best_params ? 1 : 0;
 
-                       if (candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.PARAMS)
+                       if ((candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.PARAMS) &&
+                           (candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.ARGLIST))
                                if (cand_count != argument_count)
                                        return 0;
 
@@ -4555,7 +4483,8 @@ namespace Mono.CSharp {
                ///   Determines if the candidate method, if a params method, is applicable
                ///   in its expanded form to the given set of arguments
                /// </summary>
-               static bool IsParamsMethodApplicable (EmitContext ec, ArrayList arguments, MethodBase candidate)
+               static bool IsParamsMethodApplicable (EmitContext ec, ArrayList arguments,
+                                                     MethodBase candidate, bool do_varargs)
                {
                        int arg_count;
                        
@@ -4565,16 +4494,23 @@ namespace Mono.CSharp {
                                arg_count = arguments.Count;
                        
                        ParameterData pd = GetParameterData (candidate);
-                       
-                       int pd_count = pd.Count;
 
+                       int pd_count = pd.Count;
                        if (pd_count == 0)
                                return false;
+
+                       int count = pd_count - 1;
+                       if (do_varargs) {
+                               if (pd.ParameterModifier (count) != Parameter.Modifier.ARGLIST)
+                                       return false;
+                               if (pd_count != arg_count)
+                                       return false;
+                       } else {
+                               if (pd.ParameterModifier (count) != Parameter.Modifier.PARAMS)
+                                       return false;
+                       }
                        
-                       if (pd.ParameterModifier (pd_count - 1) != Parameter.Modifier.PARAMS)
-                               return false;
-                       
-                       if (pd_count - 1 > arg_count)
+                       if (count > arg_count)
                                return false;
                        
                        if (pd_count == 1 && arg_count == 0)
@@ -4585,7 +4521,7 @@ namespace Mono.CSharp {
                        // remains is when the number of parameters is
                        // less than or equal to the argument count.
                        //
-                       for (int i = 0; i < pd_count - 1; ++i) {
+                       for (int i = 0; i < count; ++i) {
 
                                Argument a = (Argument) arguments [i];
 
@@ -4616,11 +4552,19 @@ namespace Mono.CSharp {
                                
                        }
 
+                       if (do_varargs) {
+                               Argument a = (Argument) arguments [count];
+                               if (!(a.Expr is Arglist))
+                                       return false;
+
+                               return true;
+                       }
+
                        Type element_type = TypeManager.GetElementType (pd.ParameterType (pd_count - 1));
 
                        for (int i = pd_count - 1; i < arg_count; i++) {
                                Argument a = (Argument) arguments [i];
-                               
+
                                if (!Convert.ImplicitConversionExists (ec, a.Expr, element_type))
                                        return false;
                        }
@@ -4752,7 +4696,16 @@ namespace Mono.CSharp {
                                         candidates.Add (candidate);
                                         applicable_type = candidate.DeclaringType;
                                         found_applicable = true;
-                                } else if (IsParamsMethodApplicable (ec, Arguments, candidate)) {
+                                } else if (IsParamsMethodApplicable (ec, Arguments, candidate, false)) {
+                                       if (candidate_to_form == null)
+                                               candidate_to_form = new PtrHashtable ();
+                                       
+                                       // Candidate is applicable in expanded form
+                                       candidates.Add (candidate);
+                                       applicable_type = candidate.DeclaringType;
+                                       found_applicable = true; 
+                                       candidate_to_form [candidate] = candidate;
+                                } else if (IsParamsMethodApplicable (ec, Arguments, candidate, true)) {
                                        if (candidate_to_form == null)
                                                candidate_to_form = new PtrHashtable ();
                                        
@@ -4914,7 +4867,7 @@ namespace Mono.CSharp {
                {
                        ParameterData pd = GetParameterData (method);
                        int pd_count = pd.Count;
-                       
+
                        for (int j = 0; j < argument_count; j++) {
                                Argument a = (Argument) Arguments [j];
                                Expression a_expr = a.Expr;
@@ -4932,6 +4885,8 @@ namespace Mono.CSharp {
 
                                        if (chose_params_expanded)
                                                parameter_type = TypeManager.GetElementType (parameter_type);
+                               } else if (pm == Parameter.Modifier.ARGLIST){
+                                       continue;
                                } else {
                                        //
                                        // Check modifiers
@@ -5079,7 +5034,7 @@ namespace Mono.CSharp {
                                if (TypeManager.IsSpecialMethod (method))
                                        Report.Error (571, loc, method.Name + ": can not call operator or accessor");
                        }
-                       
+
                        eclass = ExprClass.Value;
                        return this;
                }
@@ -5181,6 +5136,20 @@ namespace Mono.CSharp {
                        }
                }
 
+               static Type[] GetVarargsTypes (EmitContext ec, MethodBase mb,
+                                              ArrayList arguments)
+               {
+                       ParameterData pd = GetParameterData (mb);
+
+                       if (arguments == null)
+                               return new Type [0];
+
+                       Argument a = (Argument) arguments [pd.Count - 1];
+                       Arglist list = (Arglist) a.Expr;
+
+                       return list.ArgumentTypes;
+               }
+
                /// <summary>
                /// This checks the ConditionalAttribute on the method 
                /// </summary>
@@ -5311,23 +5280,29 @@ namespace Mono.CSharp {
                        }
 
                        EmitArguments (ec, method, Arguments);
+
+                       OpCode call_op;
+                       if (is_static || struct_call || is_base || (this_call && !method.IsVirtual))
+                               call_op = OpCodes.Call;
+                       else
+                               call_op = OpCodes.Callvirt;
+
+                       if ((method.CallingConvention & CallingConventions.VarArgs) != 0) {
+                               Type[] varargs_types = GetVarargsTypes (ec, method, Arguments);
+                               ig.EmitCall (call_op, (MethodInfo) method, varargs_types);
+                               return;
+                       }
+
                        //
                        // If you have:
                        // this.DoFoo ();
                        // and DoFoo is not virtual, you can omit the callvirt,
                        // because you don't need the null checking behavior.
                        //
-                       if (is_static || struct_call || is_base || (this_call && !method.IsVirtual)){
-                               if (method is MethodInfo) {
-                                       ig.Emit (OpCodes.Call, (MethodInfo) method);
-                               } else
-                                       ig.Emit (OpCodes.Call, (ConstructorInfo) method);
-                       } else {
-                               if (method is MethodInfo)
-                                       ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
-                               else
-                                       ig.Emit (OpCodes.Callvirt, (ConstructorInfo) method);
-                       }
+                       if (method is MethodInfo)
+                               ig.Emit (call_op, (MethodInfo) method);
+                       else
+                               ig.Emit (call_op, (ConstructorInfo) method);
                }
                
                public override void Emit (EmitContext ec)
@@ -5870,7 +5845,7 @@ namespace Mono.CSharp {
                                        Expression tmp = (Expression) o;
                                        tmp = tmp.Resolve (ec);
                                        if (tmp == null)
-                                               continue;
+                                               return false;
 
                                        // Console.WriteLine ("I got: " + tmp);
                                        // Handle initialization from vars, fields etc.
@@ -6044,10 +6019,12 @@ namespace Mono.CSharp {
 
                        if (type == null)
                                return false;
-
-                       underlying_type = type;
-                       if (underlying_type.IsArray)
-                               underlying_type = TypeManager.GetElementType (underlying_type);
+                       
+                       if (!type.IsArray) {
+                               Error (622, "Can only use array initializer expressions to assign to array types. Try using a new expression instead.");
+                               return false;
+                       }
+                       underlying_type = TypeManager.GetElementType (type);
                        dimensions = type.GetArrayRank ();
 
                        return true;
@@ -6623,6 +6600,85 @@ namespace Mono.CSharp {
                }
        }
 
+       /// <summary>
+       ///   Represents the `__arglist' construct
+       /// </summary>
+       public class ArglistAccess : Expression
+       {
+               public ArglistAccess (Location loc)
+               {
+                       this.loc = loc;
+               }
+
+               public bool ResolveBase (EmitContext ec)
+               {
+                       eclass = ExprClass.Variable;
+                       type = TypeManager.runtime_argument_handle_type;
+                       return true;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       if (!ResolveBase (ec))
+                               return null;
+
+                       if (ec.IsFieldInitializer || !ec.CurrentBlock.HasVarargs) {
+                               Error (190, "The __arglist construct is valid only within " +
+                                      "a variable argument method.");
+                               return null;
+                       }
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ec.ig.Emit (OpCodes.Arglist);
+               }
+       }
+
+       /// <summary>
+       ///   Represents the `__arglist (....)' construct
+       /// </summary>
+       public class Arglist : Expression
+       {
+               public readonly Argument[] Arguments;
+
+               public Arglist (Argument[] args, Location l)
+               {
+                       Arguments = args;
+                       loc = l;
+               }
+
+               public Type[] ArgumentTypes {
+                       get {
+                               Type[] retval = new Type [Arguments.Length];
+                               for (int i = 0; i < Arguments.Length; i++)
+                                       retval [i] = Arguments [i].Type;
+                               return retval;
+                       }
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       eclass = ExprClass.Variable;
+                       type = TypeManager.runtime_argument_handle_type;
+
+                       foreach (Argument arg in Arguments) {
+                               if (!arg.Resolve (ec, loc))
+                                       return null;
+                       }
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       foreach (Argument arg in Arguments)
+                               arg.Emit (ec);
+               }
+       }
+
        //
        // This produces the value that renders an instance, used by the iterators code
        //
@@ -6672,6 +6728,10 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       if (typearg.IsPointer && !ec.InUnsafe){
+                               UnsafeError (loc);
+                               return null;
+                       }
                        CheckObsoleteAttribute (typearg);
 
                        type = TypeManager.type_type;
@@ -6785,7 +6845,7 @@ namespace Mono.CSharp {
                                      "type name instead");
                }
 
-               static bool IdenticalNameAndTypeName (EmitContext ec, Expression left_original, Expression left, Location loc)
+               public static bool IdenticalNameAndTypeName (EmitContext ec, Expression left_original, Expression left, Location loc)
                {
                        SimpleName sn = left_original as SimpleName;
                        if (sn == null || left == null || left.Type.Name != sn.Name)
@@ -6996,7 +7056,7 @@ namespace Mono.CSharp {
                        //
 
                        Expression original = expr;
-                       expr = expr.Resolve (ec, flags | ResolveFlags.DisableFlowAnalysis);
+                       expr = expr.Resolve (ec, flags | ResolveFlags.Intermediate | ResolveFlags.DisableFlowAnalysis);
                        if (expr == null)
                                return null;
 
@@ -7306,7 +7366,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               Expression MakePointerAccess ()
+               Expression MakePointerAccess (EmitContext ec)
                {
                        Type t = Expr.Type;
 
@@ -7320,8 +7380,10 @@ namespace Mono.CSharp {
                        }
                        Expression p;
 
-                       p = new PointerArithmetic (true, Expr, ((Argument)Arguments [0]).Expr, t, loc);
-                       return new Indirection (p, loc);
+                       p = new PointerArithmetic (true, Expr, ((Argument)Arguments [0]).Expr, t, loc).Resolve (ec);
+                       if (p == null)
+                               return null;
+                       return new Indirection (p, loc).Resolve (ec);
                }
                
                public override Expression DoResolve (EmitContext ec)
@@ -7345,7 +7407,7 @@ namespace Mono.CSharp {
                        if (t.IsArray)
                                return (new ArrayAccess (this, loc)).Resolve (ec);
                        else if (t.IsPointer)
-                               return MakePointerAccess ();
+                               return MakePointerAccess (ec);
                        else
                                return (new IndexerAccess (this, loc)).Resolve (ec);
                }
@@ -7359,7 +7421,7 @@ namespace Mono.CSharp {
                        if (t.IsArray)
                                return (new ArrayAccess (this, loc)).ResolveLValue (ec, right_side);
                        else if (t.IsPointer)
-                               return MakePointerAccess ();
+                               return MakePointerAccess (ec);
                        else
                                return (new IndexerAccess (this, loc)).ResolveLValue (ec, right_side);
                }
@@ -7501,7 +7563,7 @@ namespace Mono.CSharp {
                        //Console.WriteLine (new System.Diagnostics.StackTrace ());
                        is_stobj = false;
                        t = TypeManager.TypeToCoreType (t);
-                       if (TypeManager.IsEnumType (t) && t != TypeManager.enum_type)
+                       if (TypeManager.IsEnumType (t))
                                t = TypeManager.EnumToUnderlying (t);
                        if (t == TypeManager.byte_type || t == TypeManager.sbyte_type ||
                            t == TypeManager.bool_type)
@@ -8081,6 +8143,9 @@ namespace Mono.CSharp {
 
                                pe.IsBase = true;
                        }
+                       
+                       if (e is MethodGroupExpr)
+                               ((MethodGroupExpr) e).IsBase = true;
 
                        return e;
                }
@@ -8367,6 +8432,14 @@ namespace Mono.CSharp {
                                        return null;
                        }
 
+                       Constant c = count as Constant;
+                       // TODO: because we don't have property IsNegative
+                       if (c != null && c.ConvertToUInt () == null) {
+                                // "Cannot use a negative size with stackalloc"
+                               Report.Error_T (247, loc);
+                               return null;
+                       }
+
                        if (ec.CurrentBranching.InCatch () ||
                            ec.CurrentBranching.InFinally (true)) {
                                Error (255,