提交 e84ce90f 编写于 作者: V vsadov

Call rewrite could overwrite "out" with "ref". Should not do that.

上级 bbf0a2e6
......@@ -464,7 +464,7 @@ private static bool IsSafeForReordering(BoundExpression expression, RefKind kind
// Optimize away unnecessary temporaries.
// Necessary temporaries have their store instructions merged into the appropriate
// argument expression.
OptimizeTemporaries(actualArguments, refKinds, storesToTemps, temporariesBuilder);
OptimizeTemporaries(actualArguments, storesToTemps, temporariesBuilder);
// Step two: If we have a params array, build the array and fill in the argument.
if (expanded)
......@@ -942,19 +942,16 @@ private static BoundExpression MakeLiteral(SyntaxNode syntax, ConstantValue cons
private static void OptimizeTemporaries(
BoundExpression[] arguments,
ArrayBuilder<RefKind> refKinds,
ArrayBuilder<BoundAssignmentOperator> storesToTemps,
ArrayBuilder<LocalSymbol> temporariesBuilder)
{
Debug.Assert(arguments != null);
Debug.Assert(refKinds != null);
Debug.Assert(arguments.Length == refKinds.Count);
Debug.Assert(storesToTemps != null);
Debug.Assert(temporariesBuilder != null);
if (storesToTemps.Count > 0)
{
int tempsNeeded = MergeArgumentsAndSideEffects(arguments, refKinds, storesToTemps);
int tempsNeeded = MergeArgumentsAndSideEffects(arguments,storesToTemps);
if (tempsNeeded > 0)
{
foreach (BoundAssignmentOperator s in storesToTemps)
......@@ -975,11 +972,9 @@ private static BoundExpression MakeLiteral(SyntaxNode syntax, ConstantValue cons
/// </summary>
private static int MergeArgumentsAndSideEffects(
BoundExpression[] arguments,
ArrayBuilder<RefKind> refKinds,
ArrayBuilder<BoundAssignmentOperator> tempStores)
{
Debug.Assert(arguments != null);
Debug.Assert(refKinds != null);
Debug.Assert(tempStores != null);
int tempsRemainedInUse = tempStores.Count;
......@@ -1025,11 +1020,6 @@ private static BoundExpression MakeLiteral(SyntaxNode syntax, ConstantValue cons
{
var value = tempStores[correspondingStore].Right;
// When we created the temp, we dropped the argument RefKind
// since the local contained its own RefKind. Since we're removing
// the temp, the argument RefKind needs to be restored.
refKinds[a] = ((BoundLocal)argument).LocalSymbol.RefKind;
// the matched store will not need to go into side-effects, only ones before it will
// remove the store to signal that we are not using its temp.
tempStores[correspondingStore] = null;
......
......@@ -369,5 +369,65 @@ .maxstack 2
}");
}
[WorkItem(24014, "https://github.com/dotnet/roslyn/issues/24014")]
[Fact]
public void OutParamAdOptional()
{
var code = @"
using System;
public class C
{
public static C cc => new C();
readonly int x;
readonly int y;
public static void Main()
{
var v = new C(1);
System.Console.WriteLine('Q');
}
private C()
{
}
private C(int x)
{
var c = C.cc.Test(1, this, out x, out y);
}
public C Test(object arg1, C arg2, out int i1, out int i2, object opt = null)
{
i1 = 1;
i2 = 2;
return arg2;
}
}
";
var compilation = CreateCompilationWithMscorlibAndSystemCore(code, options: TestOptions.ReleaseExe);
var verifier = CompileAndVerify(compilation, expectedOutput: "Q");
verifier.VerifyIL("C..ctor(int)", @"
{
// Code size 34 (0x22)
.maxstack 6
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: call ""C C.cc.get""
IL_000b: ldc.i4.1
IL_000c: box ""int""
IL_0011: ldarg.0
IL_0012: ldarga.s V_1
IL_0014: ldarg.0
IL_0015: ldflda ""int C.y""
IL_001a: ldnull
IL_001b: callvirt ""C C.Test(object, C, out int, out int, object)""
IL_0020: pop
IL_0021: ret
}");
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册