}
}
- public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, MemberSpec member, int arity, Location loc)
+ public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, MemberSpec member, Location loc)
{
// Better message for possible generic expressions
if (member != null && (member.Kind & MemberKind.GenericMask) != 0) {
}
}
- public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, string exprType, string name, Location loc)
+ public static void Error_TypeArgumentsCannotBeUsed (IMemberContext context, string exprType, string name, Location loc)
{
context.Module.Compiler.Report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
exprType, name);
rc.Report.Error (242, loc, "The operation in question is undefined on void pointers");
}
+ public static void Warning_UnreachableExpression (ResolveContext rc, Location loc)
+ {
+ rc.Report.Warning (429, 4, loc, "Unreachable expression code detected");
+ }
+
public ResolveFlags ExprClassToResolveFlags {
get {
switch (eclass) {
/// </remarks>
public Expression Resolve (ResolveContext ec, ResolveFlags flags)
{
- if (eclass != ExprClass.Unresolved)
+ if (eclass != ExprClass.Unresolved) {
+ if ((flags & ExprClassToResolveFlags) == 0) {
+ Error_UnexpectedKind (ec, flags, loc);
+ return null;
+ }
+
return this;
+ }
Expression e;
try {
return e;
} catch (Exception ex) {
- if (loc.IsNull || ec.Module.Compiler.Settings.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled || ex is FatalException)
+ if (loc.IsNull || ec.Module.Compiler.Settings.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled || ex is FatalException ||
+ ec.Report.Printer is NullReportPrinter)
throw;
ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message);
return e;
}
+ public Constant ResolveLabelConstant (ResolveContext rc)
+ {
+ var expr = Resolve (rc);
+ if (expr == null)
+ return null;
+
+ Constant c = expr as Constant;
+ if (c == null) {
+ if (expr.type != InternalType.ErrorType)
+ rc.Report.Error (150, expr.StartLocation, "A constant value is expected");
+
+ return null;
+ }
+
+ return c;
+ }
+
public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
rc.Module.Compiler.Report.Error (182, loc,
{
var ctors = MemberCache.FindMembers (type, Constructor.ConstructorName, true);
if (ctors == null) {
- rc.Report.SymbolRelatedToPreviousError (type);
- if (type.IsStruct) {
+ switch (type.Kind) {
+ case MemberKind.Struct:
+ rc.Report.SymbolRelatedToPreviousError (type);
// Report meaningful error for struct as they always have default ctor in C# context
OverloadResolver.Error_ConstructorMismatch (rc, type, args == null ? 0 : args.Count, loc);
- } else {
+ break;
+ case MemberKind.MissingType:
+ case MemberKind.InternalCompilerType:
+ break;
+ default:
+ rc.Report.SymbolRelatedToPreviousError (type);
rc.Report.Error (143, loc, "The class `{0}' has no constructors defined",
type.GetSignatureForError ());
+ break;
}
return null;
}
if ((restrictions & MemberLookupRestrictions.InvocableOnly) != 0) {
- if (member is MethodSpec)
+ if (member is MethodSpec) {
+ //
+ // Interface members that are hidden by class members are removed from the set. This
+ // step only has an effect if T is a type parameter and T has both an effective base
+ // class other than object and a non-empty effective interface set
+ //
+ var tps = queried_type as TypeParameterSpec;
+ if (tps != null && tps.HasTypeConstraint)
+ members = RemoveHiddenTypeParameterMethods (members);
+
return new MethodGroupExpr (members, queried_type, loc);
+ }
if (!Invocation.IsMemberInvocable (member))
continue;
return null;
}
+ static IList<MemberSpec> RemoveHiddenTypeParameterMethods (IList<MemberSpec> members)
+ {
+ if (members.Count < 2)
+ return members;
+
+ //
+ // If M is a method, then all non-method members declared in an interface declaration
+ // are removed from the set, and all methods with the same signature as M declared in
+ // an interface declaration are removed from the set
+ //
+
+ bool copied = false;
+ for (int i = 0; i < members.Count; ++i) {
+ var method = members[i] as MethodSpec;
+ if (method == null) {
+ if (!copied) {
+ copied = true;
+ members = new List<MemberSpec> (members);
+ }
+
+ members.RemoveAt (i--);
+ continue;
+ }
+
+ if (!method.DeclaringType.IsInterface)
+ continue;
+
+ for (int ii = 0; ii < members.Count; ++ii) {
+ var candidate = members[ii] as MethodSpec;
+ if (candidate == null || !candidate.DeclaringType.IsClass)
+ continue;
+
+ if (!TypeSpecComparer.Override.IsEqual (candidate.Parameters, method.Parameters))
+ continue;
+
+ if (!copied) {
+ copied = true;
+ members = new List<MemberSpec> (members);
+ }
+
+ members.RemoveAt (i--);
+ break;
+ }
+ }
+
+ return members;
+ }
+
protected virtual void Error_NegativeArrayIndex (ResolveContext ec, Location loc)
{
throw new NotImplementedException ();
ec.Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation");
}
+ public virtual void FlowAnalysis (FlowAnalysisContext fc)
+ {
+ }
+
/// <summary>
/// Returns an expression that can be used to invoke operator true
/// on the expression if it exists.
/// <summary>
/// Reports that we were expecting `expr' to be of class `expected'
/// </summary>
- public void Error_UnexpectedKind (IMemberContext ctx, Expression memberExpr, string expected, string was, Location loc)
+ public static void Error_UnexpectedKind (IMemberContext ctx, Expression memberExpr, string expected, string was, Location loc)
{
var name = memberExpr.GetSignatureForError ();
/// </summary>
public abstract class ExpressionStatement : Expression
{
+ public virtual void MarkReachable (Reachability rc)
+ {
+ }
+
public ExpressionStatement ResolveStatement (BlockContext ec)
{
Expression e = Resolve (ec);
return null;
ExpressionStatement es = e as ExpressionStatement;
- if (es == null)
+ if (es == null || e is AnonymousMethodBody)
Error_InvalidExpressionStatement (ec);
//
child.Emit (ec);
}
+ public override void FlowAnalysis (FlowAnalysisContext fc)
+ {
+ child.FlowAnalysis (fc);
+ }
+
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
#if STATIC
public static Expression Create (Expression child, TypeSpec type)
{
Constant c = child as Constant;
- if (c != null)
- return new EmptyConstantCast (c, type);
+ if (c != null) {
+ var enum_constant = c as EnumConstant;
+ if (enum_constant != null)
+ c = enum_constant.Child;
+
+ if (!(c is ReducedExpression.ReducedConstantExpression)) {
+ if (c.Type == type)
+ return c;
+
+ var res = c.ConvertImplicitly (type);
+ if (res != null)
+ return res;
+ }
+ }
EmptyCast e = child as EmptyCast;
if (e != null)
}
}
- public override Constant ConvertExplicitly(bool in_checked_context, TypeSpec target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (Child.Type == target_type)
return Child;
public override void Emit (EmitContext ec)
{
base.Emit (ec);
+ Emit (ec, mode);
+ }
+ public static void Emit (EmitContext ec, Mode mode)
+ {
if (ec.HasSet (EmitContext.Options.CheckedScope)) {
switch (mode){
case Mode.I1_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
//
public class ReducedExpression : Expression
{
- sealed class ReducedConstantExpression : EmptyConstantCast
+ public sealed class ReducedConstantExpression : EmptyConstantCast
{
readonly Expression orig_expr;
this.orig_expr = orig_expr;
}
+ public Expression OriginalExpression {
+ get {
+ return orig_expr;
+ }
+ }
+
public override Constant ConvertImplicitly (TypeSpec target_type)
{
Constant c = base.ConvertImplicitly (target_type);
{
stm.EmitStatement (ec);
}
+
+ public override void FlowAnalysis (FlowAnalysisContext fc)
+ {
+ stm.FlowAnalysis (fc);
+ }
}
readonly Expression expr, orig_expr;
expr.EmitBranchable (ec, target, on_true);
}
+ public override void FlowAnalysis (FlowAnalysisContext fc)
+ {
+ expr.FlowAnalysis (fc);
+ }
+
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
return orig_expr.MakeExpression (ctx);
{
throw new InternalErrorException ("Missing Resolve call");
}
+ }
+ public class UnreachableExpression : Expression
+ {
+ public UnreachableExpression (Expression expr)
+ {
+ this.loc = expr.Location;
+ }
+
+ public override Expression CreateExpressionTree (ResolveContext ec)
+ {
+ // TODO: is it ok
+ throw new NotImplementedException ();
+ }
+
+ protected override Expression DoResolve (ResolveContext rc)
+ {
+ throw new NotSupportedException ();
+ }
+
+ public override void FlowAnalysis (FlowAnalysisContext fc)
+ {
+ fc.Report.Warning (429, 4, loc, "Unreachable expression code detected");
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ }
+
+ public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
+ {
+ }
}
//
protected override Expression DoResolve (ResolveContext rc)
{
- var e = SimpleNameResolve (rc, null, false);
-
- var fe = e as FieldExpr;
- if (fe != null) {
- fe.VerifyAssignedStructField (rc, null);
- }
-
- return e;
+ return SimpleNameResolve (rc, null);
}
public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
{
- return SimpleNameResolve (ec, right_side, false);
+ return SimpleNameResolve (ec, right_side);
}
protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ctx)
if (ctx.CurrentType != null) {
var member = MemberLookup (ctx, false, ctx.CurrentType, Name, 0, MemberLookupRestrictions.ExactArity, loc) as MemberExpr;
if (member != null) {
- member.Error_UnexpectedKind (ctx, member, "type", member.KindName, loc);
+ Error_UnexpectedKind (ctx, member, "type", member.KindName, loc);
return;
}
}
retval = ctx.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc);
if (retval != null) {
- Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, Arity, loc);
+ Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, loc);
return;
}
}
}
- public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
+ public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
{
- FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, LookupMode.Normal, loc);
+ FullNamedExpression fne = mc.LookupNamespaceOrType (Name, Arity, LookupMode.Normal, loc);
if (fne != null) {
if (fne.Type != null && Arity > 0) {
if (HasTypeArguments) {
GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
- if (ct.ResolveAsType (ec) == null)
+ if (ct.ResolveAsType (mc) == null)
return null;
return ct;
return fne;
}
- if (Arity == 0 && Name == "dynamic" && ec.Module.Compiler.Settings.Version > LanguageVersion.V_3) {
- if (!ec.Module.PredefinedAttributes.Dynamic.IsDefined) {
- ec.Module.Compiler.Report.Error (1980, Location,
+ if (Arity == 0 && Name == "dynamic" && mc.Module.Compiler.Settings.Version > LanguageVersion.V_3) {
+ if (!mc.Module.PredefinedAttributes.Dynamic.IsDefined) {
+ mc.Module.Compiler.Report.Error (1980, Location,
"Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?",
- ec.Module.PredefinedAttributes.Dynamic.GetSignatureForError ());
+ mc.Module.PredefinedAttributes.Dynamic.GetSignatureForError ());
}
fne = new DynamicTypeExpr (loc);
- fne.ResolveAsType (ec);
+ fne.ResolveAsType (mc);
}
if (fne != null)
return fne;
- Error_TypeOrNamespaceNotFound (ec);
+ Error_TypeOrNamespaceNotFound (mc);
return null;
}
} else {
var me = MemberLookup (rc, false, rc.CurrentType, Name, Arity, restrictions & ~MemberLookupRestrictions.InvocableOnly, loc) as MemberExpr;
if (me != null) {
- me.Error_UnexpectedKind (rc, me, "method group", me.KindName, loc);
+ Error_UnexpectedKind (rc, me, "method group", me.KindName, loc);
return ErrorExpression.Instance;
}
}
e = rc.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc);
if (e != null) {
if (e.Type.Arity != Arity) {
- Error_TypeArgumentsCannotBeUsed (rc, e.Type, Arity, loc);
+ Error_TypeArgumentsCannotBeUsed (rc, e.Type, loc);
return e;
}
if (e is TypeExpr) {
- e.Error_UnexpectedKind (rc, e, "variable", e.ExprClassName, loc);
+ // TypeExpression does not have correct location
+ if (e is TypeExpression)
+ e = new TypeExpression (e.Type, loc);
+
return e;
}
}
}
}
- Expression SimpleNameResolve (ResolveContext ec, Expression right_side, bool intermediate)
+ Expression SimpleNameResolve (ResolveContext ec, Expression right_side)
{
Expression e = LookupNameExpression (ec, right_side == null ? MemberLookupRestrictions.ReadAccess : MemberLookupRestrictions.None);
if (e == null)
return null;
- if (right_side != null) {
- if (e is FullNamedExpression && e.eclass != ExprClass.Unresolved) {
- e.Error_UnexpectedKind (ec, e, "variable", e.ExprClassName, loc);
- return null;
- }
+ if (e is FullNamedExpression && e.eclass != ExprClass.Unresolved) {
+ Error_UnexpectedKind (ec, e, "variable", e.ExprClassName, loc);
+ return e;
+ }
+ if (right_side != null) {
e = e.ResolveLValue (ec, right_side);
} else {
e = e.Resolve (ec);
TypeExpr te = fne as TypeExpr;
if (te == null) {
- fne.Error_UnexpectedKind (mc, fne, "type", fne.ExprClassName, loc);
+ Error_UnexpectedKind (mc, fne, "type", fne.ExprClassName, loc);
return null;
}
//
TypeSpec[] targs = null;
if (method.DeclaringType != InstanceExpression.Type) {
- var base_override = MemberCache.FindMember (InstanceExpression.Type, new MemberFilter (method), BindingRestriction.InstanceOnly | BindingRestriction.OverrideOnly) as MethodSpec;
+ //
+ // Candidate can have inflated MVAR parameters and we need to find
+ // base match for original definition not inflated parameter types
+ //
+ var parameters = method.Parameters;
+ if (method.Arity > 0) {
+ parameters = ((IParametersMember) method.MemberDefinition).Parameters;
+ var inflated = method.DeclaringType as InflatedTypeSpec;
+ if (inflated != null) {
+ parameters = parameters.Inflate (inflated.CreateLocalInflator (rc));
+ }
+ }
+
+ var filter = new MemberFilter (method.Name, method.Arity, MemberKind.Method, parameters, null);
+ var base_override = MemberCache.FindMember (InstanceExpression.Type, filter, BindingRestriction.InstanceOnly | BindingRestriction.OverrideOnly) as MethodSpec;
if (base_override != null && base_override.DeclaringType != method.DeclaringType) {
if (base_override.IsGeneric)
targs = method.TypeArguments;
// Only base will allow this invocation to happen.
//
if (method.IsAbstract) {
+ rc.Report.SymbolRelatedToPreviousError (method);
Error_CannotCallAbstractBase (rc, method.GetSignatureForError ());
}
member.GetSignatureForError (), qualifier.GetSignatureForError (), rc.CurrentType.GetSignatureForError ());
}
+ public override void FlowAnalysis (FlowAnalysisContext fc)
+ {
+ if (InstanceExpression != null)
+ InstanceExpression.FlowAnalysis (fc);
+ }
+
public bool ResolveInstanceExpression (ResolveContext rc, Expression rhs)
{
if (!ResolveInstanceExpressionCore (rc, rhs))
//
// Check intermediate value modification which won't have any effect
//
- if (rhs != null && InstanceExpression.Type.IsStruct &&
- (InstanceExpression is PropertyExpr || InstanceExpression is IndexerExpr || InstanceExpression is Invocation)) {
+ if (rhs != null && InstanceExpression.Type.IsStruct) {
+ var fexpr = InstanceExpression as FieldExpr;
+ if (fexpr != null) {
+ if (!fexpr.Spec.IsReadOnly || rc.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.ConstructorScope))
+ return true;
+
+ if (fexpr.IsStatic) {
+ rc.Report.Error (1650, loc, "Fields of static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)",
+ fexpr.GetSignatureForError ());
+ } else {
+ rc.Report.Error (1648, loc, "Members of readonly field `{0}' cannot be modified (except in a constructor or a variable initializer)",
+ fexpr.GetSignatureForError ());
+ }
- if (rc.CurrentInitializerVariable != null) {
- rc.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
- InstanceExpression.Type.GetSignatureForError (), InstanceExpression.GetSignatureForError ());
- } else {
- rc.Report.Error (1612, loc,
- "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
- InstanceExpression.GetSignatureForError ());
+ return true;
+ }
+
+ if (InstanceExpression is PropertyExpr || InstanceExpression is IndexerExpr || InstanceExpression is Invocation) {
+ if (rc.CurrentInitializerVariable != null) {
+ rc.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
+ InstanceExpression.Type.GetSignatureForError (), InstanceExpression.GetSignatureForError ());
+ } else {
+ rc.Report.Error (1612, loc,
+ "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
+ InstanceExpression.GetSignatureForError ());
+ }
+
+ return true;
+ }
+
+ var lvr = InstanceExpression as LocalVariableReference;
+ if (lvr != null) {
+
+ if (!lvr.local_info.IsReadonly)
+ return true;
+
+ rc.Report.Error (1654, loc, "Cannot assign to members of `{0}' because it is a `{1}'",
+ InstanceExpression.GetSignatureForError (), lvr.local_info.GetReadOnlyContext ());
}
}
DeclaringType.GetSignatureForError (), rc.CurrentType.GetSignatureForError ());
}
- InstanceExpression = new This (loc);
- if (this is FieldExpr && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) {
- using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
- InstanceExpression = InstanceExpression.Resolve (rc);
- }
- } else {
- InstanceExpression = InstanceExpression.Resolve (rc);
- }
-
+ InstanceExpression = new This (loc).Resolve (rc);
return false;
}
if (me != null) {
me.ResolveInstanceExpressionCore (rc, rhs);
- // Using this check to detect probing instance expression resolve
- if (!rc.OmitStructFlowAnalysis) {
- var fe = me as FieldExpr;
- if (fe != null && fe.IsMarshalByRefAccess (rc)) {
- rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
- rc.Report.Warning (1690, 1, loc,
- "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
- me.GetSignatureForError ());
- }
+ var fe = me as FieldExpr;
+ if (fe != null && fe.IsMarshalByRefAccess (rc)) {
+ rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
+ rc.Report.Warning (1690, 1, loc,
+ "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
+ me.GetSignatureForError ());
}
return true;
}
- //
- // Run member-access postponed check once we know that
- // the expression is not field expression which is the only
- // expression which can use uninitialized this
- //
- if (InstanceExpression is This && !(this is FieldExpr) && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) {
- ((This)InstanceExpression).CheckStructThisDefiniteAssignment (rc);
- }
-
//
// Additional checks for l-value member access
//
if (ExtensionExpression == null)
return null;
+ var cand = candidates;
arguments.Insert (0, new Argument (ExtensionExpression, Argument.AType.ExtensionType));
var res = base.OverloadResolve (ec, ref arguments, ehandler ?? this, restr);
+
+ // Restore candidates in case we are running in probing mode
+ candidates = cand;
// Store resolved argument and restore original arguments
if (res == null) {
/// </summary>
public class MethodGroupExpr : MemberExpr, OverloadResolver.IBaseMembersProvider
{
+ static readonly MemberSpec[] Excluded = new MemberSpec[0];
+
protected IList<MemberSpec> Methods;
MethodSpec best_candidate;
TypeSpec best_candidate_return;
}
}
+ public bool IsConditionallyExcluded {
+ get {
+ return Methods == Excluded;
+ }
+ }
+
public override bool IsInstance {
get {
if (best_candidate != null)
}
}
+ public override bool IsSideEffectFree {
+ get {
+ return InstanceExpression == null || InstanceExpression.IsSideEffectFree;
+ }
+ }
+
public override bool IsStatic {
get {
if (best_candidate != null)
return null;
}
- if (best_candidate.IsConditionallyExcluded (ec, loc))
+ if (IsConditionallyExcluded)
ec.Report.Error (765, loc,
"Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree");
InstanceExpression = ProbeIdenticalTypeName (ec, InstanceExpression, simple_name);
}
- InstanceExpression.Resolve (ec);
+ InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup | ResolveFlags.Type);
}
}
ErrorIsInaccesible (ec, best_candidate.GetSignatureForError (), loc);
}
+ // Speed up the check by not doing it on disallowed targets
+ if (best_candidate_return.Kind == MemberKind.Void && best_candidate.IsConditionallyExcluded (ec))
+ Methods = Excluded;
+
return this;
}
//
public virtual MethodGroupExpr LookupExtensionMethod (ResolveContext rc)
{
- if (InstanceExpression == null)
+ if (InstanceExpression == null || InstanceExpression.eclass == ExprClass.Type)
return null;
- InstanceExpression = InstanceExpression.Resolve (rc);
if (!IsExtensionMethodArgument (InstanceExpression))
return null;
arg_moved = true;
}
+ if (arguments == orig_args) {
+ arguments = new Arguments (orig_args.Count);
+ arguments.AddRange (orig_args);
+ }
+
arguments[index] = arguments[i];
arguments[i] = temp;
// is used as argument or delegate conversion
//
if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) {
- return 2;
+ return parameter.IsDelegate && argument.Expr is AnonymousMethodExpression ? 2 : 3;
}
}
}
// Restore expanded arguments
- if (candidate_args != args)
- candidate_args = args;
+ candidate_args = args;
}
} while (best_candidate_rate != 0 && (type_members = base_provider.GetBaseMembers (type_members[0].DeclaringType.BaseType)) != null);
if (ta_count != best_candidate.Arity && (ta_count > 0 || ((IParametersMember) best_candidate).Parameters.IsEmpty)) {
var mg = new MethodGroupExpr (new [] { best_candidate }, best_candidate.DeclaringType, loc);
- mg.Error_TypeArgumentsCannotBeUsed (rc, best_candidate, ta_count, loc);
+ mg.Error_TypeArgumentsCannotBeUsed (rc, best_candidate, loc);
return;
}
if (ms.TypeArguments != null)
constr_ok = new ConstraintChecker (rc.MemberContext).CheckAll (ms.GetGenericMethodDefinition (), ms.TypeArguments, ms.Constraints, loc);
- if (ta_count == 0) {
+ if (ta_count == 0 && ms.TypeArguments == null) {
if (custom_errors != null && custom_errors.TypeInferenceFailed (rc, best_candidate))
return;
for (; a_idx < arg_count; a_idx++, ++a_pos) {
a = args[a_idx];
+ if (a == null)
+ continue;
+
if (p_mod != Parameter.Modifier.PARAMS) {
p_mod = pd.FixedParameters[a_idx].ModFlags;
pt = ptypes[a_idx];
"The best overloaded method match for `{0}' does not contain a parameter named `{1}'",
TypeManager.CSharpSignature (member), na.Name);
}
- } else if (args[name_index] != a) {
+ } else if (args[name_index] != a && args[name_index] != null) {
if (IsDelegateInvoke)
ec.Report.SymbolRelatedToPreviousError (DelegateType);
else
return false;
}
- Expression conv = null;
+ Expression conv;
if (a.ArgType == Argument.AType.ExtensionType) {
if (a.Expr.Type == pt || TypeSpecComparer.IsEqual (a.Expr.Type, pt)) {
conv = a.Expr;
params_initializers.Add (a.Expr);
args.RemoveAt (a_idx--);
--arg_count;
+ a.Expr = conv;
continue;
}
// "a.b" is initialized, not whether the whole struct "a" is initialized.
if (lvalue_instance) {
- using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
- bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess;
+ bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess;
- Expression right_side =
- out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
+ Expression right_side =
+ out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
- InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
- }
+ InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
} else {
- using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
- InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
- }
+ InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
}
if (InstanceExpression == null)
var fb = spec as FixedFieldSpec;
IVariableReference var = InstanceExpression as IVariableReference;
- if (lvalue_instance && var != null && var.VariableInfo != null) {
- var.VariableInfo.SetStructFieldAssigned (ec, Name);
- }
-
if (fb != null) {
IFixedExpression fe = InstanceExpression as IFixedExpression;
if (!ec.HasSet (ResolveContext.Options.FixedInitializerScope) && (fe == null || !fe.IsFixed)) {
//
if (var != null && var.VariableInfo != null && InstanceExpression.Type.IsStruct) {
variable_info = var.VariableInfo.GetStructFieldInfo (Name);
- if (rhs != null && variable_info != null)
- variable_info.SetStructFieldAssigned (ec, Name);
}
eclass = ExprClass.Variable;
return this;
}
- public void VerifyAssignedStructField (ResolveContext rc, Expression rhs)
+ public void SetFieldAssigned (FlowAnalysisContext fc)
+ {
+ if (!IsInstance)
+ return;
+
+ bool lvalue_instance = spec.DeclaringType.IsStruct;
+ if (lvalue_instance) {
+ var var = InstanceExpression as IVariableReference;
+ if (var != null && var.VariableInfo != null) {
+ fc.SetStructFieldAssigned (var.VariableInfo, Name);
+ }
+ }
+
+ var fe = InstanceExpression as FieldExpr;
+ if (fe != null || lvalue_instance) {
+ if (fe == null)
+ return;
+
+ /*
+ while (fe.InstanceExpression is FieldExpr) {
+ fe = (FieldExpr) fe.InstanceExpression;
+ if (!fe.Spec.DeclaringType.IsStruct)
+ continue;
+
+ if (fe.VariableInfo != null && fc.IsStructFieldDefinitelyAssigned (fe.VariableInfo, fe.Name)) {
+ fc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
+ }
+ }
+
+ fe.InstanceExpression.FlowAnalysis (fc);
+ */
+ } else {
+ InstanceExpression.FlowAnalysis (fc);
+ }
+ }
+
+
+ public void VerifyAssignedStructField (FlowAnalysisContext fc)
{
var fe = this;
if (var != null) {
var vi = var.VariableInfo;
- if (vi != null && !vi.IsStructFieldAssigned (rc, fe.Name) && (rhs == null || !fe.type.IsStruct)) {
- if (rhs != null) {
- rc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
- } else {
- rc.Report.Error (170, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
- }
-
- return;
+ if (vi != null && !fc.IsStructFieldDefinitelyAssigned (vi, fe.Name) && !fe.type.IsStruct) {
+ fc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
}
}
} while (fe != null);
}
- static readonly int [] codes = {
- 191, // instance, write access
- 192, // instance, out access
- 198, // static, write access
- 199, // static, out access
- 1648, // member of value instance, write access
- 1649, // member of value instance, out access
- 1650, // member of value static, write access
- 1651 // member of value static, out access
- };
-
- static readonly string [] msgs = {
- /*0191*/ "A readonly field `{0}' cannot be assigned to (except in a constructor or a variable initializer)",
- /*0192*/ "A readonly field `{0}' cannot be passed ref or out (except in a constructor)",
- /*0198*/ "A static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)",
- /*0199*/ "A static readonly field `{0}' cannot be passed ref or out (except in a static constructor)",
- /*1648*/ "Members of readonly field `{0}' cannot be modified (except in a constructor or a variable initializer)",
- /*1649*/ "Members of readonly field `{0}' cannot be passed ref or out (except in a constructor)",
- /*1650*/ "Fields of static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)",
- /*1651*/ "Fields of static readonly field `{0}' cannot be passed ref or out (except in a static constructor)"
- };
-
- // The return value is always null. Returning a value simplifies calling code.
- Expression Report_AssignToReadonly (ResolveContext ec, Expression right_side)
- {
- int i = 0;
- if (right_side == EmptyExpression.OutAccess || right_side == EmptyExpression.LValueMemberOutAccess)
- i += 1;
- if (IsStatic)
- i += 2;
- if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess)
- i += 4;
- ec.Report.Error (codes [i], loc, msgs [i], GetSignatureForError ());
+ Expression Error_AssignToReadonly (ResolveContext rc, Expression right_side)
+ {
+ // The return value is always null. Returning a value simplifies calling code.
+
+ if (right_side == EmptyExpression.OutAccess) {
+ if (IsStatic) {
+ rc.Report.Error (199, loc, "A static readonly field `{0}' cannot be passed ref or out (except in a static constructor)",
+ GetSignatureForError ());
+ } else {
+ rc.Report.Error (192, loc, "A readonly field `{0}' cannot be passed ref or out (except in a constructor)",
+ GetSignatureForError ());
+ }
+
+ return null;
+ }
+
+ if (right_side == EmptyExpression.LValueMemberAccess) {
+ // Already reported as CS1648/CS1650
+ return null;
+ }
+
+ if (right_side == EmptyExpression.LValueMemberOutAccess) {
+ if (IsStatic) {
+ rc.Report.Error (1651, loc, "Fields of static readonly field `{0}' cannot be passed ref or out (except in a static constructor)",
+ GetSignatureForError ());
+ } else {
+ rc.Report.Error (1649, loc, "Members of readonly field `{0}' cannot be passed ref or out (except in a constructor)",
+ GetSignatureForError ());
+ }
+ return null;
+ }
+
+ if (IsStatic) {
+ rc.Report.Error (198, loc, "A static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)",
+ GetSignatureForError ());
+ } else {
+ rc.Report.Error (191, loc, "A readonly field `{0}' cannot be assigned to (except in a constructor or a variable initializer)",
+ GetSignatureForError ());
+ }
return null;
}
-
+
override public Expression DoResolveLValue (ResolveContext ec, Expression right_side)
{
if (spec is FixedFieldSpec) {
if (spec.IsReadOnly) {
// InitOnly fields can only be assigned in constructors or initializers
if (!ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.ConstructorScope))
- return Report_AssignToReadonly (ec, right_side);
+ return Error_AssignToReadonly (ec, right_side);
if (ec.HasSet (ResolveContext.Options.ConstructorScope)) {
// InitOnly fields cannot be assigned-to in a different constructor from their declaring type
if (ec.CurrentMemberDefinition.Parent.PartialContainer.Definition != spec.DeclaringType.GetDefinition ())
- return Report_AssignToReadonly (ec, right_side);
+ return Error_AssignToReadonly (ec, right_side);
// static InitOnly fields cannot be assigned-to in an instance constructor
if (IsStatic && !ec.IsStatic)
- return Report_AssignToReadonly (ec, right_side);
+ return Error_AssignToReadonly (ec, right_side);
// instance constructors can't modify InitOnly fields of other instances of the same type
if (!IsStatic && !(InstanceExpression is This))
- return Report_AssignToReadonly (ec, right_side);
+ return Error_AssignToReadonly (ec, right_side);
}
}
return this;
}
+ public override void FlowAnalysis (FlowAnalysisContext fc)
+ {
+ var var = InstanceExpression as IVariableReference;
+ if (var != null) {
+ var vi = var.VariableInfo;
+ if (vi != null && !fc.IsStructFieldDefinitelyAssigned (vi, Name)) {
+ fc.Report.Error (170, loc, "Use of possibly unassigned field `{0}'", Name);
+ return;
+ }
+
+ if (TypeSpec.IsValueType (InstanceExpression.Type))
+ return;
+ }
+
+ base.FlowAnalysis (fc);
+ }
+
public override int GetHashCode ()
{
return spec.GetHashCode ();
}
}
} else {
- args = arguments == null ? new Arguments (1) : arguments;
+ args = arguments ?? new Arguments (1);
if (leave_copy) {
source.Emit (ec);
best_candidate.GetSignatureForError ());
return false;
}
- } else if (!best_candidate.Get.IsAccessible (rc)) {
+ } else if (!best_candidate.Get.IsAccessible (rc) || !best_candidate.Get.DeclaringType.IsAccessible (rc)) {
if (best_candidate.HasDifferentAccessibility) {
rc.Report.SymbolRelatedToPreviousError (best_candidate.Get);
rc.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because the get accessor is inaccessible",
return false;
}
- if (!best_candidate.Set.IsAccessible (rc)) {
+ if (!best_candidate.Set.IsAccessible (rc) || !best_candidate.Set.DeclaringType.IsAccessible (rc)) {
if (best_candidate.HasDifferentAccessibility) {
rc.Report.SymbolRelatedToPreviousError (best_candidate.Set);
rc.Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible",
DoEmit (ec);
}
+ protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+ {
+ return false;
+ }
+
protected override void CloneTo (CloneContext clonectx, Statement target)
{
// Nothing
// Don't capture temporary variables except when using
// state machine redirection and block yields
//
- if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod is StateMachineInitializer &&
+ if (ec.CurrentAnonymousMethod is StateMachineInitializer &&
(ec.CurrentBlock.Explicit.HasYield || ec.CurrentBlock.Explicit.HasAwait) &&
ec.IsVariableCapturingRequired) {
AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec);
public override VariableInfo VariableInfo {
get { return null; }
}
-
- public override void VerifyAssigned (ResolveContext rc)
- {
- }
}
///