Skip to content

Commit

Permalink
Always use a by-value temp to capture a reference type receiver
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouv committed May 23, 2024
1 parent 5ac052e commit 99e5c2f
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 172 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -677,17 +677,24 @@ private ImmutableArray<BoundExpression> VisitArgumentsAndCaptureReceiverIfNeeded
}
else
{
refKind = rewrittenReceiver.GetRefKind();

if (refKind == RefKind.None &&
!rewrittenReceiver.Type.IsReferenceType &&
Binder.HasHome(rewrittenReceiver,
Binder.AddressKind.Constrained,
_factory.CurrentFunction,
peVerifyCompatEnabled: false,
stackLocalsOpt: null))
if (rewrittenReceiver.Type.IsReferenceType)
{
refKind = RefKind.Ref;
refKind = RefKind.None;
}
else
{
refKind = rewrittenReceiver.GetRefKind();

if (refKind == RefKind.None &&
!rewrittenReceiver.Type.IsReferenceType &&
Binder.HasHome(rewrittenReceiver,
Binder.AddressKind.Constrained,
_factory.CurrentFunction,
peVerifyCompatEnabled: false,
stackLocalsOpt: null))
{
refKind = RefKind.Ref;
}
}
}

Expand Down
50 changes: 23 additions & 27 deletions src/Compilers/CSharp/Test/Emit2/CodeGen/CodeGenCallTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2137,36 +2137,32 @@ public DummyHandler(int literalLength, int formattedCount, IMoveable logger)
verifier.VerifyIL("Program.Call1<T>",
@"
{
// Code size 70 (0x46)
// Code size 61 (0x3d)
.maxstack 6
.locals init (T& V_0,
T V_1,
DummyHandler V_2)
.locals init (T V_0,
DummyHandler V_1)
IL_0000: ldarg.0
IL_0001: ldobj ""T""
IL_0006: stloc.1
IL_0007: ldloca.s V_1
IL_0009: stloc.0
IL_000a: ldloc.0
IL_000b: ldarg.0
IL_000c: call ""int Program.GetOffset<T>(ref T)""
IL_0011: ldloca.s V_2
IL_0013: ldc.i4.4
IL_0014: ldc.i4.1
IL_0015: ldloc.0
IL_0016: ldobj ""T""
IL_001b: box ""T""
IL_0020: call ""DummyHandler..ctor(int, int, IMoveable)""
IL_0025: ldloca.s V_2
IL_0027: ldstr ""log:""
IL_002c: call ""void DummyHandler.AppendLiteral(string)""
IL_0031: ldloca.s V_2
IL_0033: ldc.i4.0
IL_0034: call ""void DummyHandler.AppendFormatted<int>(int)""
IL_0039: ldloc.2
IL_003a: constrained. ""T""
IL_0040: callvirt ""void IMoveable.GetName(int, DummyHandler)""
IL_0045: ret
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: box ""T""
IL_000d: ldarg.0
IL_000e: call ""int Program.GetOffset<T>(ref T)""
IL_0013: ldloca.s V_1
IL_0015: ldc.i4.4
IL_0016: ldc.i4.1
IL_0017: ldloc.0
IL_0018: box ""T""
IL_001d: call ""DummyHandler..ctor(int, int, IMoveable)""
IL_0022: ldloca.s V_1
IL_0024: ldstr ""log:""
IL_0029: call ""void DummyHandler.AppendLiteral(string)""
IL_002e: ldloca.s V_1
IL_0030: ldc.i4.0
IL_0031: call ""void DummyHandler.AppendFormatted<int>(int)""
IL_0036: ldloc.1
IL_0037: callvirt ""void IMoveable.GetName(int, DummyHandler)""
IL_003c: ret
}
");

Expand Down
180 changes: 88 additions & 92 deletions src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9716,61 +9716,60 @@ public CustomHandler(int literalLength, int formattedCount," + refness + @" C c)
verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.FailsILVerify : Verification.Skipped);
verifier.VerifyIL("<top-level-statements-entry-point>", refness == "in" ? @"
{
// Code size 46 (0x2e)
// Code size 47 (0x2f)
.maxstack 4
.locals init (C V_0, //c
C& V_1,
C V_1,
CustomHandler V_2)
IL_0000: ldc.i4.1
IL_0001: newobj ""C..ctor(int)""
IL_0006: stloc.0
IL_0007: ldloca.s V_0
IL_0009: call ""ref C Program.<<Main>$>g__GetC|0_0(ref C)""
IL_000e: stloc.1
IL_000f: ldloc.1
IL_0010: ldind.ref
IL_000e: ldind.ref
IL_000f: stloc.1
IL_0010: ldloc.1
IL_0011: ldc.i4.7
IL_0012: ldc.i4.0
IL_0013: ldloc.1
IL_0014: newobj ""CustomHandler..ctor(int, int, in C)""
IL_0019: stloc.2
IL_001a: ldloca.s V_2
IL_001c: ldstr ""literal""
IL_0021: call ""bool CustomHandler.AppendLiteral(string)""
IL_0026: pop
IL_0027: ldloc.2
IL_0028: callvirt ""void C.M(CustomHandler)""
IL_002d: ret
IL_0013: ldloca.s V_1
IL_0015: newobj ""CustomHandler..ctor(int, int, in C)""
IL_001a: stloc.2
IL_001b: ldloca.s V_2
IL_001d: ldstr ""literal""
IL_0022: call ""bool CustomHandler.AppendLiteral(string)""
IL_0027: pop
IL_0028: ldloc.2
IL_0029: callvirt ""void C.M(CustomHandler)""
IL_002e: ret
}
"
: @"
{
// Code size 48 (0x30)
// Code size 47 (0x2f)
.maxstack 5
.locals init (C V_0, //c
C& V_1,
C V_1,
CustomHandler V_2)
IL_0000: ldc.i4.1
IL_0001: newobj ""C..ctor(int)""
IL_0006: stloc.0
IL_0007: ldloca.s V_0
IL_0009: call ""ref C Program.<<Main>$>g__GetC|0_0(ref C)""
IL_000e: stloc.1
IL_000f: ldloc.1
IL_0010: ldind.ref
IL_000e: ldind.ref
IL_000f: stloc.1
IL_0010: ldloc.1
IL_0011: ldloca.s V_2
IL_0013: ldc.i4.7
IL_0014: ldc.i4.0
IL_0015: ldloc.1
IL_0016: ldind.ref
IL_0017: call ""CustomHandler..ctor(int, int, C)""
IL_001c: ldloca.s V_2
IL_001e: ldstr ""literal""
IL_0023: call ""bool CustomHandler.AppendLiteral(string)""
IL_0028: pop
IL_0029: ldloc.2
IL_002a: callvirt ""void C.M(CustomHandler)""
IL_002f: ret
IL_0016: call ""CustomHandler..ctor(int, int, C)""
IL_001b: ldloca.s V_2
IL_001d: ldstr ""literal""
IL_0022: call ""bool CustomHandler.AppendLiteral(string)""
IL_0027: pop
IL_0028: ldloc.2
IL_0029: callvirt ""void C.M(CustomHandler)""
IL_002e: ret
}
");

Expand Down Expand Up @@ -9822,31 +9821,30 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL
verifier.VerifyDiagnostics();
verifier.VerifyIL($"Program.<<Main>$>g__localFunc|0_0({parameterRefness} C)", @"
{
// Code size 43 (0x2b)
// Code size 42 (0x2a)
.maxstack 5
.locals init (C& V_0,
.locals init (C V_0,
CustomHandler V_1)
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: newobj ""C..ctor(int)""
IL_0007: stind.ref
IL_0008: ldarg.0
IL_0009: stloc.0
IL_000a: ldloc.0
IL_000b: ldind.ref
IL_0009: ldind.ref
IL_000a: stloc.0
IL_000b: ldloc.0
IL_000c: ldloca.s V_1
IL_000e: ldc.i4.7
IL_000f: ldc.i4.0
IL_0010: ldloc.0
IL_0011: ldind.ref
IL_0012: call ""CustomHandler..ctor(int, int, C)""
IL_0017: ldloca.s V_1
IL_0019: ldstr ""literal""
IL_001e: call ""bool CustomHandler.AppendLiteral(string)""
IL_0023: pop
IL_0024: ldloc.1
IL_0025: callvirt ""void C.M(CustomHandler)""
IL_002a: ret
IL_0011: call ""CustomHandler..ctor(int, int, C)""
IL_0016: ldloca.s V_1
IL_0018: ldstr ""literal""
IL_001d: call ""bool CustomHandler.AppendLiteral(string)""
IL_0022: pop
IL_0023: ldloc.1
IL_0024: callvirt ""void C.M(CustomHandler)""
IL_0029: ret
}
");

Expand Down Expand Up @@ -18585,41 +18583,40 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL

verifier.VerifyIL("<top-level-statements-entry-point>", """
{
// Code size 53 (0x35)
.maxstack 5
.locals init (C V_0, //c
C& V_1, //c2
C V_2, //otherC
C& V_3,
CustomHandler V_4)
IL_0000: ldc.i4.5
IL_0001: newobj "C..ctor(int)"
IL_0006: stloc.0
IL_0007: ldloca.s V_0
IL_0009: stloc.1
IL_000a: ldnull
IL_000b: stloc.2
IL_000c: ldloc.1
IL_000d: stloc.3
IL_000e: ldloc.3
IL_000f: ldind.ref
IL_0010: ldloca.s V_4
IL_0012: ldc.i4.7
IL_0013: ldc.i4.0
IL_0014: ldloc.3
IL_0015: ldind.ref
IL_0016: call "CustomHandler..ctor(int, int, C)"
IL_001b: ldloca.s V_4
IL_001d: ldstr "literal"
IL_0022: call "bool CustomHandler.AppendLiteral(string)"
IL_0027: pop
IL_0028: ldloc.s V_4
IL_002a: ldloca.s V_2
IL_002c: dup
IL_002d: stloc.1
IL_002e: ldind.ref
IL_002f: callvirt "void C.M(CustomHandler, C)"
IL_0034: ret
// Code size 52 (0x34)
.maxstack 5
.locals init (C V_0, //c
C& V_1, //c2
C V_2, //otherC
C V_3,
CustomHandler V_4)
IL_0000: ldc.i4.5
IL_0001: newobj "C..ctor(int)"
IL_0006: stloc.0
IL_0007: ldloca.s V_0
IL_0009: stloc.1
IL_000a: ldnull
IL_000b: stloc.2
IL_000c: ldloc.1
IL_000d: ldind.ref
IL_000e: stloc.3
IL_000f: ldloc.3
IL_0010: ldloca.s V_4
IL_0012: ldc.i4.7
IL_0013: ldc.i4.0
IL_0014: ldloc.3
IL_0015: call "CustomHandler..ctor(int, int, C)"
IL_001a: ldloca.s V_4
IL_001c: ldstr "literal"
IL_0021: call "bool CustomHandler.AppendLiteral(string)"
IL_0026: pop
IL_0027: ldloc.s V_4
IL_0029: ldloca.s V_2
IL_002b: dup
IL_002c: stloc.1
IL_002d: ldind.ref
IL_002e: callvirt "void C.M(CustomHandler, C)"
IL_0033: ret
}
""");
}
Expand Down Expand Up @@ -18669,12 +18666,12 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL

verifier.VerifyIL("<top-level-statements-entry-point>", """
{
// Code size 53 (0x35)
// Code size 52 (0x34)
.maxstack 6
.locals init (C V_0, //c
C& V_1, //c2
C V_2, //otherC
C& V_3,
C V_3,
CustomHandler V_4)
IL_0000: ldc.i4.5
IL_0001: newobj "C..ctor(int)"
Expand All @@ -18684,9 +18681,9 @@ .locals init (C V_0, //c
IL_000a: ldnull
IL_000b: stloc.2
IL_000c: ldloc.1
IL_000d: stloc.3
IL_000e: ldloc.3
IL_000f: ldind.ref
IL_000d: ldind.ref
IL_000e: stloc.3
IL_000f: ldloc.3
IL_0010: ldloca.s V_2
IL_0012: dup
IL_0013: stloc.1
Expand All @@ -18695,15 +18692,14 @@ .locals init (C V_0, //c
IL_0017: ldc.i4.7
IL_0018: ldc.i4.0
IL_0019: ldloc.3
IL_001a: ldind.ref
IL_001b: call "CustomHandler..ctor(int, int, C)"
IL_0020: ldloca.s V_4
IL_0022: ldstr "literal"
IL_0027: call "bool CustomHandler.AppendLiteral(string)"
IL_002c: pop
IL_002d: ldloc.s V_4
IL_002f: callvirt "void C.M(C, CustomHandler)"
IL_0034: ret
IL_001a: call "CustomHandler..ctor(int, int, C)"
IL_001f: ldloca.s V_4
IL_0021: ldstr "literal"
IL_0026: call "bool CustomHandler.AppendLiteral(string)"
IL_002b: pop
IL_002c: ldloc.s V_4
IL_002e: callvirt "void C.M(C, CustomHandler)"
IL_0033: ret
}
""");
}
Expand Down
Loading

0 comments on commit 99e5c2f

Please sign in to comment.