Fix Firebird 'make dist' and build
[mono.git] / mcs / gmcs / expression.cs
index 960ef21944cf6e130a299f4d502a8a851c409c06..1d35cb53fec2c5cc52974b9b5b05976b2347588c 100644 (file)
@@ -1231,7 +1231,7 @@ namespace Mono.CSharp {
                        eclass = ExprClass.Value;
                        Type etype = expr.Type;
 
-                       if (TypeManager.IsValueType (probe_type)){
+                       if (probe_type.IsValueType) {
                                Report.Error (77, loc, "The as operator must be used with a reference type (`" +
                                              TypeManager.CSharpName (probe_type) + "' is a value type)");
                                return null;
@@ -1349,7 +1349,7 @@ namespace Mono.CSharp {
                        if (expr.Type == target_type)
                                return expr;
 
-                       if (TypeManager.IsEnumType (target_type))
+                       if (TypeManager.IsEnumType (target_type) && TypeManager.EnumToUnderlying (target_type) == expr.Type)
                                return new EnumConstant ((Constant)expr, target_type);
 
                        Expression real_expr = expr;
@@ -2304,7 +2304,7 @@ namespace Mono.CSharp {
                                                return null;
                                        }
 
-                                       left = new BoxedCast (left);
+                                       left = new BoxedCast (left, TypeManager.object_type);
                                        Type = TypeManager.bool_type;
                                        return this;
                                }
@@ -2315,7 +2315,7 @@ namespace Mono.CSharp {
                                                return null;
                                        }
 
-                                       right = new BoxedCast (right);
+                                       right = new BoxedCast (right, TypeManager.object_type);
                                        Type = TypeManager.bool_type;
                                        return this;
                                }
@@ -2964,7 +2964,8 @@ namespace Mono.CSharp {
 
                private void WarnUselessComparison (Type type)
                {
-                       Report.Warning (652, 2, loc, "Comparison to integral constant is useless; the constant is outside the range of type '{0}'", type);
+                       Report.Warning (652, 2, loc, "Comparison to integral constant is useless; the constant is outside the range of type `{0}'",
+                               TypeManager.CSharpName (type));
                }
 
                /// <remarks>
@@ -3755,6 +3756,11 @@ namespace Mono.CSharp {
                                        return null;
                        }
                        
+                       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 = ?");
+                       }
+
                        trueExpr = trueExpr.Resolve (ec);
                        falseExpr = falseExpr.Resolve (ec);
 
@@ -3868,6 +3874,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool VerifyAssigned (EmitContext ec)
+               {
+                       VariableInfo variable_info = local_info.VariableInfo;
+                       return variable_info == null || variable_info.IsAssigned (ec, loc);
+               }
+
                protected Expression DoResolveBase (EmitContext ec, Expression lvalue_right_side)
                {
                        if (local_info == null) {
@@ -3905,7 +3917,7 @@ namespace Mono.CSharp {
                                return e.Resolve (ec);
                        }
 
-                       if ((variable_info != null) && !variable_info.IsAssigned (ec, loc))
+                       if (!VerifyAssigned (ec))
                                return null;
 
                        if (lvalue_right_side == null)
@@ -4997,7 +5009,7 @@ namespace Mono.CSharp {
                                if (a_mod == p_mod ||
                                    (a_mod == Parameter.Modifier.NONE && p_mod == Parameter.Modifier.PARAMS)) {
                                        if (a_mod == Parameter.Modifier.NONE) {
-                                                if (!Convert.ImplicitConversionExists (ec,
+                                                if (!TypeManager.IsEqual (a.Type, pd.ParameterType (i)) && !Convert.ImplicitConversionExists (ec,
                                                                                        a.Expr,
                                                                                        pd.ParameterType (i)))
                                                        return false;
@@ -5154,7 +5166,13 @@ namespace Mono.CSharp {
 
                                        VerifyArgumentsCompat (ec, Arguments, arg_count,
                                                c, false, null, may_fail, loc);
-                                        break;
+
+                                       if (!may_fail && errors == Report.Errors)
+                                               throw new InternalErrorException (
+                                                       "VerifyArgumentsCompat and IsApplicable do not agree; " +
+                                                       "likely reason: ImplicitConversion and ImplicitConversionExists have gone out of sync");
+
+                                       break;
                                }
 
                                if (!may_fail && errors == Report.Errors) {
@@ -5538,12 +5556,8 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if ((method.Attributes & MethodAttributes.SpecialName) != 0){
-                               if (TypeManager.LookupDeclSpace (method.DeclaringType) != null || TypeManager.IsSpecialMethod (method)) {
-                                       Report.Error (571, loc, "`{0}': cannot explicitly call operator or accessor",
-                                               TypeManager.CSharpSignature (method, true));
-                                       return null;
-                               }
+                       if ((method.Attributes & MethodAttributes.SpecialName) != 0 && IsSpecialMethodInvocation (method)) {
+                               return null;
                        }
                        
                        if (mg.InstanceExpression != null)
@@ -5553,6 +5567,32 @@ namespace Mono.CSharp {
                        return this;
                }
 
+               bool IsSpecialMethodInvocation (MethodBase method)
+               {
+                       IMethodData md = TypeManager.GetMethod (method);
+                       if (md != null) {
+                               if (!(md is AbstractPropertyEventMethod) && !(md is Operator))
+                                       return false;
+                       } else {
+                               if (!TypeManager.IsSpecialMethod (method))
+                                       return false;
+
+                               int args = TypeManager.GetParameterData (method).Count;
+                               if (method.Name.StartsWith ("get_") && args > 0)
+                                       return false;
+                               else if (method.Name.StartsWith ("set_") && args > 2)
+                                       return false;
+
+                               // TODO: check operators and events as well ?
+                       }
+
+                       Report.SymbolRelatedToPreviousError (method);
+                       Report.Error (571, loc, "`{0}': cannot explicitly call operator or accessor",
+                               TypeManager.CSharpSignature (method, true));
+       
+                       return true;
+               }
+
                // <summary>
                //   Emits the list of arguments as an array
                // </summary>
@@ -5798,7 +5838,7 @@ namespace Mono.CSharp {
                                if (!omit_args) {
                                        Type t = null;
                                        if (this_call) {
-                                               ig.Emit (OpCodes.Ldarg_0);
+                                               ec.EmitThis ();
                                                t = decl_type;
                                        } else {
                                                Type iexpr_type = instance_expr.Type;
@@ -6190,11 +6230,13 @@ namespace Mono.CSharp {
                        }
 
                        if (type.IsAbstract && type.IsSealed) {
+                               Report.SymbolRelatedToPreviousError (type);
                                Report.Error (712, loc, "Cannot create an instance of the static class `{0}'", TypeManager.CSharpName (type));
                                return null;
                        }
 
                        if (type.IsInterface || type.IsAbstract){
+                               Report.SymbolRelatedToPreviousError (type);
                                Report.Error (144, loc, "Cannot create an instance of the abstract class or interface `{0}'", TypeManager.CSharpName (type));
                                return null;
                        }
@@ -6964,7 +7006,7 @@ namespace Mono.CSharp {
                                        if (e is StringConstant || e is DecimalConstant || !(e is Constant) ||
                                            num_automatic_initializers <= max_automatic_initializers) {
                                                Type etype = e.Type;
-                                               
+
                                                ig.Emit (OpCodes.Dup);
 
                                                for (int idx = 0; idx < dims; idx++) 
@@ -6974,7 +7016,8 @@ namespace Mono.CSharp {
                                                // If we are dealing with a struct, get the
                                                // address of it, so we can store it.
                                                //
-                                               if ((dims == 1) && etype.IsValueType &&
+                                               if ((dims == 1) && 
+                                                   TypeManager.IsValueType (etype) &&
                                                    (!TypeManager.IsBuiltinOrEnum (etype) ||
                                                     etype == TypeManager.decimal_type)) {
                                                        if (e is New){
@@ -7675,15 +7718,22 @@ namespace Mono.CSharp {
                                return mg.ResolveGeneric (ec, args);
                        }
 
+                       if (original != null && !TypeManager.IsValueType (expr_type)) {
+                               me = member_lookup as MemberExpr;
+                               if (me != null && me.IsInstance) {
+                                       LocalVariableReference var = new_expr as LocalVariableReference;
+                                       if (var != null && !var.VerifyAssigned (ec))
+                                               return null;
+                               }
+                       }
+
                        // The following DoResolve/DoResolveLValue will do the definite assignment
                        // check.
 
                        if (right_side != null)
-                               member_lookup = member_lookup.DoResolveLValue (ec, right_side);
+                               return member_lookup.DoResolveLValue (ec, right_side);
                        else
-                               member_lookup = member_lookup.DoResolve (ec);
-
-                       return member_lookup;
+                               return member_lookup.DoResolve (ec);
                }
 
                public override Expression DoResolve (EmitContext ec)