X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fexpression.cs;h=1d35cb53fec2c5cc52974b9b5b05976b2347588c;hb=bd316288ae3fa0cb6f03b367716d04d5244c5d04;hp=960ef21944cf6e130a299f4d502a8a851c409c06;hpb=10511a5881a30b7ad78a29d4db912b2726c53619;p=mono.git diff --git a/mcs/gmcs/expression.cs b/mcs/gmcs/expression.cs index 960ef21944c..1d35cb53fec 100644 --- a/mcs/gmcs/expression.cs +++ b/mcs/gmcs/expression.cs @@ -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)); } /// @@ -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; + } + // // Emits the list of arguments as an array // @@ -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)