From bacb293db8e88e27f26e9671457ffc62f043b03f Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 11 Nov 2017 17:55:22 +0100 Subject: [PATCH] Fix #971: Anonymous method with missing parameter name --- .../TestCases/Pretty/DelegateConstruction.cs | 6 +++ .../TestCases/Pretty/DelegateConstruction.il | 45 +++++++++++++++++-- .../Pretty/DelegateConstruction.opt.il | 36 +++++++++++++-- .../Pretty/DelegateConstruction.opt.roslyn.il | 32 ++++++++++++- .../Pretty/DelegateConstruction.roslyn.il | 39 +++++++++++++++- .../TestCases/Pretty/InitializerTests.cs | 2 +- .../TestCases/Pretty/PropertiesAndEvents.cs | 2 +- .../CSharp/ExpressionBuilder.cs | 21 ++++----- 8 files changed, 157 insertions(+), 26 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.cs index e665d9ba0..e39e9f5f8 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.cs @@ -127,6 +127,12 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty }); } + public Action Bug971_DelegateWithoutParameterList() + { + return delegate { + }; + } + private void DoAction(Action action) { } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.il index e578c4088..ff6fa69d0 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.il @@ -15,7 +15,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly '0kytvwpf' +.assembly awc2kjfz { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) @@ -26,15 +26,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module '0kytvwpf.dll' -// MVID: {BE56C518-B5DE-4D51-B8A3-26964CEEA341} +.module awc2kjfz.dll +// MVID: {49C8B10E-CA57-40C1-9484-BC8636C38817} .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .imagebase 0x10000000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00FC0000 +// Image base: 0x04D50000 // =============== CLASS MEMBERS DECLARATION =================== @@ -404,6 +404,8 @@ .field private static class [mscorlib]System.Threading.ThreadStart 'CS$<>9__CachedAnonymousMethodDelegate35' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Action`1 'CS$<>9__CachedAnonymousMethodDelegate43' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .method public hidebysig instance class [mscorlib]System.Action CaptureOfThis() cil managed { @@ -828,6 +830,31 @@ IL_0029: ret } // end of method InstanceTests::Bug951c + .method public hidebysig instance class [mscorlib]System.Action`1 + Bug971_DelegateWithoutParameterList() cil managed + { + // Code size 37 (0x25) + .maxstack 2 + .locals init (class [mscorlib]System.Action`1 V_0) + IL_0000: nop + IL_0001: ldsfld class [mscorlib]System.Action`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests::'CS$<>9__CachedAnonymousMethodDelegate43' + IL_0006: brtrue.s IL_001b + + IL_0008: ldnull + IL_0009: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests::'b__42'(object) + IL_000f: newobj instance void class [mscorlib]System.Action`1::.ctor(object, + native int) + IL_0014: stsfld class [mscorlib]System.Action`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests::'CS$<>9__CachedAnonymousMethodDelegate43' + IL_0019: br.s IL_001b + + IL_001b: ldsfld class [mscorlib]System.Action`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests::'CS$<>9__CachedAnonymousMethodDelegate43' + IL_0020: stloc.0 + IL_0021: br.s IL_0023 + + IL_0023: ldloc.0 + IL_0024: ret + } // end of method InstanceTests::Bug971_DelegateWithoutParameterList + .method private hidebysig instance void DoAction(class [mscorlib]System.Action action) cil managed { @@ -904,6 +931,16 @@ IL_0001: ret } // end of method InstanceTests::'b__34' + .method private hidebysig static void + 'b__42'(object param0) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method InstanceTests::'b__42' + } // end of class InstanceTests .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass1' diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.opt.il index 4e699787b..8d2c56f1d 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.opt.il @@ -15,7 +15,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly yf3oha4w +.assembly ci3jaj4f { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) @@ -26,15 +26,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module yf3oha4w.dll -// MVID: {CDC95C8E-FB20-4924-8805-3F3D95A5736B} +.module ci3jaj4f.dll +// MVID: {F860E23B-9B90-453A-A3A5-49C4D5AA91F8} .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .imagebase 0x10000000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00AB0000 +// Image base: 0x05340000 // =============== CLASS MEMBERS DECLARATION =================== @@ -373,6 +373,8 @@ .field private static class [mscorlib]System.Threading.ThreadStart 'CS$<>9__CachedAnonymousMethodDelegate35' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Action`1 'CS$<>9__CachedAnonymousMethodDelegate43' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .method public hidebysig instance class [mscorlib]System.Action CaptureOfThis() cil managed { @@ -709,6 +711,23 @@ IL_0026: ret } // end of method InstanceTests::Bug951c + .method public hidebysig instance class [mscorlib]System.Action`1 + Bug971_DelegateWithoutParameterList() cil managed + { + // Code size 30 (0x1e) + .maxstack 8 + IL_0000: ldsfld class [mscorlib]System.Action`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests::'CS$<>9__CachedAnonymousMethodDelegate43' + IL_0005: brtrue.s IL_0018 + + IL_0007: ldnull + IL_0008: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests::'b__42'(object) + IL_000e: newobj instance void class [mscorlib]System.Action`1::.ctor(object, + native int) + IL_0013: stsfld class [mscorlib]System.Action`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests::'CS$<>9__CachedAnonymousMethodDelegate43' + IL_0018: ldsfld class [mscorlib]System.Action`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests::'CS$<>9__CachedAnonymousMethodDelegate43' + IL_001d: ret + } // end of method InstanceTests::Bug971_DelegateWithoutParameterList + .method private hidebysig instance void DoAction(class [mscorlib]System.Action action) cil managed { @@ -775,6 +794,15 @@ IL_0000: ret } // end of method InstanceTests::'b__34' + .method private hidebysig static void + 'b__42'(object param0) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method InstanceTests::'b__42' + } // end of class InstanceTests .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass1' diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.opt.roslyn.il index 0fe0c1e4d..17e0d0801 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.opt.roslyn.il @@ -31,14 +31,14 @@ .ver 0:0:0:0 } .module DelegateConstruction.dll -// MVID: {F5BE0762-9125-4B48-8F46-BEC064B8B43B} +// MVID: {BCE55681-8792-49AA-A3A8-0599BF49400D} .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .imagebase 0x10000000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x010B0000 +// Image base: 0x04FD0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -228,6 +228,7 @@ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c' '<>9' .field public static class [mscorlib]System.Threading.ThreadStart '<>9__8_0' + .field public static class [mscorlib]System.Action`1 '<>9__12_0' .method private hidebysig specialname rtspecialname static void .cctor() cil managed { @@ -256,6 +257,14 @@ IL_0000: ret } // end of method '<>c'::'b__8_0' + .method assembly hidebysig instance void + 'b__12_0'(object '') cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method '<>c'::'b__12_0' + } // end of class '<>c' .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass9_0' @@ -726,6 +735,25 @@ IL_0026: ret } // end of method InstanceTests::Bug951c + .method public hidebysig instance class [mscorlib]System.Action`1 + Bug971_DelegateWithoutParameterList() cil managed + { + // Code size 32 (0x20) + .maxstack 8 + IL_0000: ldsfld class [mscorlib]System.Action`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c'::'<>9__12_0' + IL_0005: dup + IL_0006: brtrue.s IL_001f + + IL_0008: pop + IL_0009: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c'::'<>9' + IL_000e: ldftn instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c'::'b__12_0'(object) + IL_0014: newobj instance void class [mscorlib]System.Action`1::.ctor(object, + native int) + IL_0019: dup + IL_001a: stsfld class [mscorlib]System.Action`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c'::'<>9__12_0' + IL_001f: ret + } // end of method InstanceTests::Bug971_DelegateWithoutParameterList + .method private hidebysig instance void DoAction(class [mscorlib]System.Action action) cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.roslyn.il index 53296d13b..20264ea53 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.roslyn.il @@ -31,14 +31,14 @@ .ver 0:0:0:0 } .module DelegateConstruction.dll -// MVID: {6914DD72-BE03-4BA0-9025-522152E6E42F} +// MVID: {06FD5D29-DFCF-456A-A796-15359E05F003} .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .imagebase 0x10000000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x010C0000 +// Image base: 0x011B0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -237,6 +237,7 @@ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c' '<>9' .field public static class [mscorlib]System.Threading.ThreadStart '<>9__8_0' + .field public static class [mscorlib]System.Action`1 '<>9__12_0' .method private hidebysig specialname rtspecialname static void .cctor() cil managed { @@ -267,6 +268,15 @@ IL_0001: ret } // end of method '<>c'::'b__8_0' + .method assembly hidebysig instance void + 'b__12_0'(object '') cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method '<>c'::'b__12_0' + } // end of class '<>c' .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass9_0' @@ -823,6 +833,31 @@ IL_0028: ret } // end of method InstanceTests::Bug951c + .method public hidebysig instance class [mscorlib]System.Action`1 + Bug971_DelegateWithoutParameterList() cil managed + { + // Code size 37 (0x25) + .maxstack 2 + .locals init (class [mscorlib]System.Action`1 V_0) + IL_0000: nop + IL_0001: ldsfld class [mscorlib]System.Action`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c'::'<>9__12_0' + IL_0006: dup + IL_0007: brtrue.s IL_0020 + + IL_0009: pop + IL_000a: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c'::'<>9' + IL_000f: ldftn instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c'::'b__12_0'(object) + IL_0015: newobj instance void class [mscorlib]System.Action`1::.ctor(object, + native int) + IL_001a: dup + IL_001b: stsfld class [mscorlib]System.Action`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction/InstanceTests/'<>c'::'<>9__12_0' + IL_0020: stloc.0 + IL_0021: br.s IL_0023 + + IL_0023: ldloc.0 + IL_0024: ret + } // end of method InstanceTests::Bug971_DelegateWithoutParameterList + .method private hidebysig instance void DoAction(class [mscorlib]System.Action action) cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs index 2ed1d3953..b02789cd7 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs @@ -272,7 +272,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public static void NotAnObjectInitializerWithEvent() { Data data = new Data(); - data.TestEvent += delegate(object sender, EventArgs e) { + data.TestEvent += delegate { Console.WriteLine(); }; InitializerTests.X(InitializerTests.Y(), data); diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/PropertiesAndEvents.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/PropertiesAndEvents.cs index 3da7eada2..b20cb9cb3 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/PropertiesAndEvents.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/PropertiesAndEvents.cs @@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public event EventHandler AutomaticEvent; [field: NonSerialized] - public event EventHandler AutomaticEventWithInitializer = delegate(object sender, EventArgs e) { + public event EventHandler AutomaticEventWithInitializer = delegate { }; public event EventHandler CustomEvent { diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 5ca393c28..8e86d6d52 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1367,18 +1367,15 @@ namespace ICSharpCode.Decompiler.CSharp // otherwise use lambda only if an expression lambda is possible isLambda = (body.Statements.Count == 1 && body.Statements.Single() is ReturnStatement); } - // Remove the parameter list from an AnonymousMethodExpression if the original method had no names, - // and the parameters are not used in the method body - if (!isLambda && method.Parameters.All(p => string.IsNullOrEmpty(p.Name))) { - var parameterReferencingIdentifiers = - from ident in body.Descendants.OfType() - let v = ident.Annotation()?.Variable - where v != null && v.Kind == VariableKind.Parameter - select ident; - if (!parameterReferencingIdentifiers.Any()) { - ame.Parameters.Clear(); - ame.HasParameterList = false; - } + // Remove the parameter list from an AnonymousMethodExpression if the parameters are not used in the method body + var parameterReferencingIdentifiers = + from ident in body.Descendants.OfType() + let v = ident.GetILVariable() + where v != null && v.Function == function && v.Kind == VariableKind.Parameter + select ident; + if (!isLambda && !parameterReferencingIdentifiers.Any()) { + ame.Parameters.Clear(); + ame.HasParameterList = false; } Expression replacement;