From 704ca7886ead5c0013f839d18b0338fbf4fabe55 Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Tue, 18 Mar 2014 16:41:18 +0100 Subject: [PATCH] [mcs] Emit field initializer with expression tree in all user constructors. Fixes #18308 --- mcs/mcs/anonymous.cs | 2 +- mcs/mcs/assign.cs | 10 ++++++++-- mcs/mcs/class.cs | 14 +++++++++++++- mcs/mcs/convert.cs | 1 + mcs/mcs/ecore.cs | 8 ++++++++ mcs/mcs/expression.cs | 4 ++++ mcs/tests/gtest-etree-30.cs | 30 ++++++++++++++++++++++++++++++ 7 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 mcs/tests/gtest-etree-30.cs diff --git a/mcs/mcs/anonymous.cs b/mcs/mcs/anonymous.cs index e5cb73dd94beb..4aafffe5678ea 100644 --- a/mcs/mcs/anonymous.cs +++ b/mcs/mcs/anonymous.cs @@ -1267,7 +1267,7 @@ public Expression Compatible (ResolveContext ec, TypeSpec type) throw new InternalErrorException (e, loc); } - if (!ec.IsInProbingMode) { + if (!ec.IsInProbingMode && !etree_conversion) { compatibles.Add (type, am ?? EmptyExpression.Null); } diff --git a/mcs/mcs/assign.cs b/mcs/mcs/assign.cs index 9481aef96edae..97125dbaf04a4 100644 --- a/mcs/mcs/assign.cs +++ b/mcs/mcs/assign.cs @@ -334,7 +334,7 @@ protected override Expression DoResolve (ResolveContext ec) if (source == null) { ok = false; - source = EmptyExpression.Null; + source = ErrorExpression.Instance; } target = target.ResolveLValue (ec, source); @@ -589,6 +589,12 @@ public FieldInitializer (FieldBase mc, Expression expression, Location loc) public int AssignmentOffset { get; private set; } + public FieldBase Field { + get { + return mc; + } + } + public override Location StartLocation { get { return loc; @@ -601,8 +607,8 @@ protected override Expression DoResolve (ResolveContext rc) if (source == null) return null; - var bc = (BlockContext) rc; if (resolved == null) { + var bc = (BlockContext) rc; var ctx = new FieldInitializerContext (mc, bc); resolved = base.DoResolve (ctx) as ExpressionStatement; AssignmentOffset = ctx.AssignmentInfoOffset - bc.AssignmentInfoOffset; diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs index d450030d747eb..be497a1750dc8 100644 --- a/mcs/mcs/class.cs +++ b/mcs/mcs/class.cs @@ -1010,9 +1010,20 @@ public void ResolveFieldInitializers (BlockContext ec) for (int i = 0; i < initialized_fields.Count; ++i) { FieldInitializer fi = initialized_fields [i]; + + // + // Clone before resolving otherwise when field initializer is needed + // in more than 1 constructor any resolve after the initial one would + // only took the resolved expression which is problem for expressions + // that generate extra expressions or code during Resolve phase + // + var cloned = fi.Clone (new CloneContext ()); + ExpressionStatement s = fi.ResolveStatement (ec); - if (s == null) + if (s == null) { + initialized_fields [i] = new FieldInitializer (fi.Field, ErrorExpression.Instance, Location.Null); continue; + } // // Field is re-initialized to its default value => removed @@ -1022,6 +1033,7 @@ public void ResolveFieldInitializers (BlockContext ec) ec.AssignmentInfoOffset += fi.AssignmentOffset; ec.CurrentBlock.AddScopeStatement (new StatementExpression (s)); + initialized_fields [i] = (FieldInitializer) cloned; } } diff --git a/mcs/mcs/convert.cs b/mcs/mcs/convert.cs index 6fc03b11d9e03..ebc4355483b38 100644 --- a/mcs/mcs/convert.cs +++ b/mcs/mcs/convert.cs @@ -1467,6 +1467,7 @@ static Expression ImplicitConversionStandard (ResolveContext ec, Expression expr return e; source.Error_ValueCannotBeConverted (ec, target_type, false); + return null; } diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index 8a6a88f3cb819..0b73b3656cbdf 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -5792,6 +5792,14 @@ public void SetHasAddressTaken () } } + protected override void CloneTo (CloneContext clonectx, Expression target) + { + var t = (FieldExpr) target; + + if (InstanceExpression != null) + t.InstanceExpression = InstanceExpression.Clone (clonectx); + } + public override Expression CreateExpressionTree (ResolveContext ec) { return CreateExpressionTree (ec, true); diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs index 0c78f1abbe464..41b1d77a4e372 100644 --- a/mcs/mcs/expression.cs +++ b/mcs/mcs/expression.cs @@ -9999,6 +9999,10 @@ public EmptyExpression (TypeSpec t) loc = Location.Null; } + protected override void CloneTo (CloneContext clonectx, Expression target) + { + } + public override bool ContainsEmitWithAwait () { return false; diff --git a/mcs/tests/gtest-etree-30.cs b/mcs/tests/gtest-etree-30.cs new file mode 100644 index 0000000000000..0c8ec7e6bd44c --- /dev/null +++ b/mcs/tests/gtest-etree-30.cs @@ -0,0 +1,30 @@ +using System; +using System.Linq.Expressions; + +public sealed class C +{ + public C () + { + } + + public C (Action tappedCallback) + { + } + + public readonly string TappedCallbackProperty = Create> (o => o.TappedCallback); + + public Action TappedCallback { + get; + set; + } + + public static string Create (Expression> getter) + { + return null; + } + + public static void Main () + { + new C (null); + } +}