Skip to content

Commit 62bde56

Browse files
committed
Fix ParentFlags handling in TryEmitNewExpression
* new ParentFlags is created, similarly to TryEmitMethodCall - this avoids unwanted propagation of IgnoreResult, MemberAccess, ... * handle ParentFlags.InstanceAccess - emit load address instruction * set closure.LastEmitIsAddress (this should be reset to avoid leaking this value from the emit of last argument) * handle IgnoresResult
1 parent 0457a35 commit 62bde56

1 file changed

Lines changed: 19 additions & 8 deletions

File tree

src/FastExpressionCompiler/FastExpressionCompiler.cs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2430,7 +2430,7 @@ private static bool TryEmitNew(Expression expr, IReadOnlyList<PE> paramExprs, IL
24302430
CompilerFlags setup, ParentFlags parent)
24312431
#endif
24322432
{
2433-
parent |= ParentFlags.CtorCall;
2433+
var flags = ParentFlags.CtorCall;
24342434
var newExpr = (NewExpression)expr;
24352435
#if SUPPORTS_ARGUMENT_PROVIDER
24362436
var argExprs = (IArgumentProvider)newExpr;
@@ -2449,15 +2449,15 @@ private static bool TryEmitNew(Expression expr, IReadOnlyList<PE> paramExprs, IL
24492449
// see the #488 for the details.
24502450
if (argCount == 1)
24512451
{
2452-
if (!TryEmit(argExprs.GetArgument(0), paramExprs, il, ref closure, setup, parent, pars[0].ParameterType.IsByRef ? 0 : -1))
2452+
if (!TryEmit(argExprs.GetArgument(0), paramExprs, il, ref closure, setup, flags, pars[0].ParameterType.IsByRef ? 0 : -1))
24532453
return false;
24542454
}
24552455
else
24562456
{
24572457
if (!closure.ArgsContainingComplexExpression.Map.ContainsKey(newExpr))
24582458
{
24592459
for (var i = 0; i < argCount; ++i)
2460-
if (!TryEmit(argExprs.GetArgument(i), paramExprs, il, ref closure, setup, parent, pars[i].ParameterType.IsByRef ? i : -1))
2460+
if (!TryEmit(argExprs.GetArgument(i), paramExprs, il, ref closure, setup, flags, pars[i].ParameterType.IsByRef ? i : -1))
24612461
return false;
24622462
}
24632463
else
@@ -2467,7 +2467,7 @@ private static bool TryEmitNew(Expression expr, IReadOnlyList<PE> paramExprs, IL
24672467
{
24682468
var argExpr = argExprs.GetArgument(i);
24692469
var parType = pars[i].ParameterType;
2470-
if (!TryEmit(argExpr, paramExprs, il, ref closure, setup, parent, parType.IsByRef ? i : -1))
2470+
if (!TryEmit(argExpr, paramExprs, il, ref closure, setup, flags, parType.IsByRef ? i : -1))
24712471
return false;
24722472
argVars.Add(EmitStoreLocalVariable(il, parType));
24732473
}
@@ -2476,21 +2476,32 @@ private static bool TryEmitNew(Expression expr, IReadOnlyList<PE> paramExprs, IL
24762476
}
24772477
}
24782478
}
2479+
var newType = newExpr.Type;
24792480
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
24802481
if (ctor != null)
24812482
il.Demit(OpCodes.Newobj, ctor);
2482-
else if (newExpr.Type.IsValueType)
2483+
else if (newType.IsValueType)
24832484
{
2484-
ctor = newExpr.Type.GetConstructor(
2485+
ctor = newType.GetConstructor(
24852486
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
24862487
default, CallingConventions.Any, Tools.Empty<Type>(), default);
24872488
if (ctor != null)
24882489
il.Demit(OpCodes.Newobj, ctor);
24892490
else
2490-
EmitLoadLocalVariable(il, InitValueTypeVariable(il, newExpr.Type));
2491+
EmitLoadLocalVariable(il, InitValueTypeVariable(il, newType));
24912492
}
24922493
else
24932494
return false;
2495+
2496+
closure.LastEmitIsAddress = newType.IsValueType && (parent & ParentFlags.InstanceAccess) != 0 && !parent.IgnoresResult();
2497+
if (closure.LastEmitIsAddress)
2498+
{
2499+
EmitStoreAndLoadLocalVariableAddress(il, newType);
2500+
}
2501+
2502+
if (parent.IgnoresResult())
2503+
il.Demit(OpCodes.Pop);
2504+
24942505
return true;
24952506
}
24962507

@@ -5081,7 +5092,7 @@ public static bool TryEmitMemberGet(MemberExpression expr,
50815092
// if the field is not used as an index, #302
50825093
// or if the field is not accessed from the just constructed object `new Widget().DodgyValue`, #333
50835094
if (((parent & ParentFlags.InstanceAccess) != 0 &
5084-
(parent & (ParentFlags.IndexAccess | ParentFlags.Ctor)) == 0) && field.FieldType.IsValueType)
5095+
(parent & ParentFlags.IndexAccess) == 0) && field.FieldType.IsValueType)
50855096
isByAddress = true;
50865097

50875098
// we don't need to duplicate the instance if we are working with the field address to save to it directly,

0 commit comments

Comments
 (0)