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;
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;
return null;
}
- left = new BoxedCast (left);
+ left = new BoxedCast (left, TypeManager.object_type);
Type = TypeManager.bool_type;
return this;
}
return null;
}
- right = new BoxedCast (right);
+ right = new BoxedCast (right, TypeManager.object_type);
Type = TypeManager.bool_type;
return this;
}
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>
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);
}
}
+ 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) {
return e.Resolve (ec);
}
- if ((variable_info != null) && !variable_info.IsAssigned (ec, loc))
+ if (!VerifyAssigned (ec))
return null;
if (lvalue_right_side == null)
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;
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) {
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)
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>
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;
}
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;
}
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++)
// 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){
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)