From 25356c8c5b9f898f90b89b80eedcfed6119b68a1 Mon Sep 17 00:00:00 2001 From: Charles Stoner Date: Mon, 3 May 2021 10:09:58 -0700 Subject: [PATCH] Correct closure info for bound sequence points (#52987) --- .../Portable/Lowering/SpillSequenceSpiller.cs | 6 +- .../CSharp/Test/Emit/PDB/PDBTests.cs | 457 +++++++++++++++++- 2 files changed, 453 insertions(+), 10 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs b/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs index e76c80f2e1c36..a8770d3e0a476 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs @@ -5,15 +5,11 @@ #nullable disable using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Linq; -using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.CSharp.Symbols; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis.Operations; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp @@ -274,7 +270,7 @@ private BoundStatement UpdateStatement(BoundSpillSequenceBuilder builder, BoundS builder.AddStatement(statement); } - var result = _F.Block(builder.GetLocals(), builder.GetStatements()); + var result = new BoundBlock(statement.Syntax, builder.GetLocals(), builder.GetStatements()) { WasCompilerGenerated = true }; builder.Free(); return result; diff --git a/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs b/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs index 4626deb25162b..7305f8a802c28 100644 --- a/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs +++ b/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs @@ -9625,9 +9625,9 @@ .locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0 - + - + @@ -9641,7 +9641,7 @@ .locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0 - + @@ -9649,8 +9649,8 @@ .locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0 0 - - + + @@ -9731,6 +9731,453 @@ .locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0 "); } + [WorkItem(50321, "https://github.com/dotnet/roslyn/issues/50321")] + [ConditionalFact(typeof(CoreClrOnly))] + public void NestedSwitchExpressions_Closures_01() + { + string source = WithWindowsLineBreaks( +@"using System; +class C +{ + static int F(object o) + { + return o switch + { + int i => new Func(() => i + i switch + { + 1 => 2, + _ => 3 + })(), + _ => 4 + }; + } +}"); + var verifier = CompileAndVerify(source, options: TestOptions.DebugDll); + verifier.VerifyTypeIL("C", +@".class private auto ansi beforefieldinit C + extends [netstandard]System.Object +{ + // Nested Types + .class nested private auto ansi sealed beforefieldinit '<>c__DisplayClass0_0' + extends [netstandard]System.Object + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Fields + .field public int32 '5__2' + // Methods + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x20a1 + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [netstandard]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method '<>c__DisplayClass0_0'::.ctor + .method assembly hidebysig + instance int32 'b__0' () cil managed + { + // Method begins at RVA 0x20ac + // Code size 38 (0x26) + .maxstack 2 + .locals init ( + [0] int32, + [1] int32 + ) + IL_0000: ldarg.0 + IL_0001: ldfld int32 C/'<>c__DisplayClass0_0'::'5__2' + IL_0006: stloc.0 + IL_0007: ldc.i4.1 + IL_0008: brtrue.s IL_000b + IL_000a: nop + IL_000b: ldarg.0 + IL_000c: ldfld int32 C/'<>c__DisplayClass0_0'::'5__2' + IL_0011: ldc.i4.1 + IL_0012: beq.s IL_0016 + IL_0014: br.s IL_001a + IL_0016: ldc.i4.2 + IL_0017: stloc.1 + IL_0018: br.s IL_001e + IL_001a: ldc.i4.3 + IL_001b: stloc.1 + IL_001c: br.s IL_001e + IL_001e: ldc.i4.1 + IL_001f: brtrue.s IL_0022 + IL_0021: nop + IL_0022: ldloc.0 + IL_0023: ldloc.1 + IL_0024: add + IL_0025: ret + } // end of method '<>c__DisplayClass0_0'::'b__0' + } // end of class <>c__DisplayClass0_0 + // Methods + .method private hidebysig static + int32 F ( + object o + ) cil managed + { + // Method begins at RVA 0x2050 + // Code size 69 (0x45) + .maxstack 2 + .locals init ( + [0] class C/'<>c__DisplayClass0_0', + [1] int32, + [2] int32 + ) + IL_0000: nop + IL_0001: newobj instance void C/'<>c__DisplayClass0_0'::.ctor() + IL_0006: stloc.0 + IL_0007: ldc.i4.1 + IL_0008: brtrue.s IL_000b + IL_000a: nop + IL_000b: ldarg.0 + IL_000c: isinst [netstandard]System.Int32 + IL_0011: brfalse.s IL_0037 + IL_0013: ldloc.0 + IL_0014: ldarg.0 + IL_0015: unbox.any [netstandard]System.Int32 + IL_001a: stfld int32 C/'<>c__DisplayClass0_0'::'5__2' + IL_001f: br.s IL_0021 + IL_0021: br.s IL_0023 + IL_0023: ldloc.0 + IL_0024: ldftn instance int32 C/'<>c__DisplayClass0_0'::'b__0'() + IL_002a: newobj instance void class [netstandard]System.Func`1::.ctor(object, native int) + IL_002f: callvirt instance !0 class [netstandard]System.Func`1::Invoke() + IL_0034: stloc.1 + IL_0035: br.s IL_003b + IL_0037: ldc.i4.4 + IL_0038: stloc.1 + IL_0039: br.s IL_003b + IL_003b: ldc.i4.1 + IL_003c: brtrue.s IL_003f + IL_003e: nop + IL_003f: ldloc.1 + IL_0040: stloc.2 + IL_0041: br.s IL_0043 + IL_0043: ldloc.2 + IL_0044: ret + } // end of method C::F + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x20a1 + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [netstandard]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method C::.ctor +} // end of class C +"); + verifier.VerifyPdb( +@" + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"); + } + + [WorkItem(50321, "https://github.com/dotnet/roslyn/issues/50321")] + [ConditionalFact(typeof(CoreClrOnly))] + public void NestedSwitchExpressions_Closures_02() + { + string source = WithWindowsLineBreaks( +@"using System; +class C +{ + static string F(object o) + { + return o switch + { + int i => new Func(() => ""1"" + i switch + { + 1 => new Func(() => ""2"" + i)(), + _ => ""3"" + })(), + _ => ""4"" + }; + } +}"); + var verifier = CompileAndVerify(source, options: TestOptions.DebugDll); + verifier.VerifyTypeIL("C", +@".class private auto ansi beforefieldinit C + extends [netstandard]System.Object +{ + // Nested Types + .class nested private auto ansi sealed beforefieldinit '<>c__DisplayClass0_0' + extends [netstandard]System.Object + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Fields + .field public int32 '5__2' + .field public class [netstandard]System.Func`1 '<>9__1' + // Methods + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x20a5 + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [netstandard]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method '<>c__DisplayClass0_0'::.ctor + .method assembly hidebysig + instance string 'b__0' () cil managed + { + // Method begins at RVA 0x20b0 + // Code size 78 (0x4e) + .maxstack 3 + .locals init ( + [0] string, + [1] class [netstandard]System.Func`1 + ) + IL_0000: ldc.i4.1 + IL_0001: brtrue.s IL_0004 + IL_0003: nop + IL_0004: ldarg.0 + IL_0005: ldfld int32 C/'<>c__DisplayClass0_0'::'5__2' + IL_000a: ldc.i4.1 + IL_000b: beq.s IL_000f + IL_000d: br.s IL_0036 + IL_000f: ldarg.0 + IL_0010: ldfld class [netstandard]System.Func`1 C/'<>c__DisplayClass0_0'::'<>9__1' + IL_0015: dup + IL_0016: brtrue.s IL_002e + IL_0018: pop + IL_0019: ldarg.0 + IL_001a: ldarg.0 + IL_001b: ldftn instance string C/'<>c__DisplayClass0_0'::'b__1'() + IL_0021: newobj instance void class [netstandard]System.Func`1::.ctor(object, native int) + IL_0026: dup + IL_0027: stloc.1 + IL_0028: stfld class [netstandard]System.Func`1 C/'<>c__DisplayClass0_0'::'<>9__1' + IL_002d: ldloc.1 + IL_002e: callvirt instance !0 class [netstandard]System.Func`1::Invoke() + IL_0033: stloc.0 + IL_0034: br.s IL_003e + IL_0036: ldstr ""3"" + IL_003b: stloc.0 + IL_003c: br.s IL_003e + IL_003e: ldc.i4.1 + IL_003f: brtrue.s IL_0042 + IL_0041: nop + IL_0042: ldstr ""1"" + IL_0047: ldloc.0 + IL_0048: call string [netstandard]System.String::Concat(string, string) + IL_004d: ret + } // end of method '<>c__DisplayClass0_0'::'b__0' + .method assembly hidebysig + instance string 'b__1' () cil managed + { + // Method begins at RVA 0x210a + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldstr ""2"" + IL_0005: ldarg.0 + IL_0006: ldflda int32 C/'<>c__DisplayClass0_0'::'5__2' + IL_000b: call instance string [netstandard]System.Int32::ToString() + IL_0010: call string [netstandard]System.String::Concat(string, string) + IL_0015: ret + } // end of method '<>c__DisplayClass0_0'::'b__1' + } // end of class <>c__DisplayClass0_0 + // Methods + .method private hidebysig static + string F ( + object o + ) cil managed + { + // Method begins at RVA 0x2050 + // Code size 73 (0x49) + .maxstack 2 + .locals init ( + [0] class C/'<>c__DisplayClass0_0', + [1] string, + [2] string + ) + IL_0000: nop + IL_0001: newobj instance void C/'<>c__DisplayClass0_0'::.ctor() + IL_0006: stloc.0 + IL_0007: ldc.i4.1 + IL_0008: brtrue.s IL_000b + IL_000a: nop + IL_000b: ldarg.0 + IL_000c: isinst [netstandard]System.Int32 + IL_0011: brfalse.s IL_0037 + IL_0013: ldloc.0 + IL_0014: ldarg.0 + IL_0015: unbox.any [netstandard]System.Int32 + IL_001a: stfld int32 C/'<>c__DisplayClass0_0'::'5__2' + IL_001f: br.s IL_0021 + IL_0021: br.s IL_0023 + IL_0023: ldloc.0 + IL_0024: ldftn instance string C/'<>c__DisplayClass0_0'::'b__0'() + IL_002a: newobj instance void class [netstandard]System.Func`1::.ctor(object, native int) + IL_002f: callvirt instance !0 class [netstandard]System.Func`1::Invoke() + IL_0034: stloc.1 + IL_0035: br.s IL_003f + IL_0037: ldstr ""4"" + IL_003c: stloc.1 + IL_003d: br.s IL_003f + IL_003f: ldc.i4.1 + IL_0040: brtrue.s IL_0043 + IL_0042: nop + IL_0043: ldloc.1 + IL_0044: stloc.2 + IL_0045: br.s IL_0047 + IL_0047: ldloc.2 + IL_0048: ret + } // end of method C::F + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x20a5 + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [netstandard]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method C::.ctor +} // end of class C +"); + verifier.VerifyPdb( +@" + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"); + } + [WorkItem(37261, "https://github.com/dotnet/roslyn/issues/37261")] [ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)] public void SwitchExpression_MethodBody()