From 6f032e267eb00f82e5cb220bfe51ffb244829c71 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 9 Oct 2021 00:32:14 +0200 Subject: [PATCH] Fix #2515: Auto events are not decompiled correctly, if left untouched. --- .../ICSharpCode.Decompiler.Tests.csproj | 2 + .../Ugly/NoPropertiesAndEvents.Expected.cs | 69 +++++++++ .../TestCases/Ugly/NoPropertiesAndEvents.cs | 27 ++++ .../TestCases/Ugly/NoPropertiesAndEvents.il | 136 ++++++++++++++++++ .../Ugly/NoPropertiesAndEvents.opt.il | 124 ++++++++++++++++ .../Ugly/NoPropertiesAndEvents.opt.roslyn.il | 131 +++++++++++++++++ .../Ugly/NoPropertiesAndEvents.roslyn.il | 133 +++++++++++++++++ .../UglyTestRunner.cs | 9 ++ .../CSharp/ExpressionBuilder.cs | 4 + 9 files changed, 635 insertions(+) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.Expected.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.opt.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.opt.roslyn.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.roslyn.il diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 1e4e1bf2e2..c8aa7e614e 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -109,6 +109,8 @@ + + diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.Expected.cs b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.Expected.cs new file mode 100644 index 0000000000..f153dbe603 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.Expected.cs @@ -0,0 +1,69 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +#if ROSLYN +#if !OPT +using System.Diagnostics; +#endif +using System.Runtime.CompilerServices; +#endif +using System.Threading; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Ugly +{ + internal class NoPropertiesAndEvents + { +#if ROSLYN + [CompilerGenerated] +#if !OPT + [DebuggerBrowsable(DebuggerBrowsableState.Never)] +#endif +#endif + private EventHandler m_MyEvent; + + public event EventHandler MyEvent { +#if ROSLYN + [CompilerGenerated] +#endif + add { + EventHandler eventHandler = this.m_MyEvent; + EventHandler eventHandler2; + do + { + eventHandler2 = eventHandler; + EventHandler value2 = (EventHandler)Delegate.Combine(eventHandler2, value); + eventHandler = Interlocked.CompareExchange(ref this.m_MyEvent, value2, eventHandler2); + } while ((object)eventHandler != eventHandler2); + } +#if ROSLYN + [CompilerGenerated] +#endif + remove { + EventHandler eventHandler = this.m_MyEvent; + EventHandler eventHandler2; + do + { + eventHandler2 = eventHandler; + EventHandler value2 = (EventHandler)Delegate.Remove(eventHandler2, value); + eventHandler = Interlocked.CompareExchange(ref this.m_MyEvent, value2, eventHandler2); + } while ((object)eventHandler != eventHandler2); + } + } + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.cs b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.cs new file mode 100644 index 0000000000..06a684cbb6 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.cs @@ -0,0 +1,27 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Ugly +{ + internal class NoPropertiesAndEvents + { + public event EventHandler MyEvent; + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.il b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.il new file mode 100644 index 0000000000..98fb8d1d7e --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.il @@ -0,0 +1,136 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly tmp8FA +{ + .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.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module tmp8FA.tmp +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents + extends [mscorlib]System.Object +{ + .field private class [mscorlib]System.EventHandler MyEvent + .method public hidebysig specialname instance void + add_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + // Code size 48 (0x30) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2, + bool V_3) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: ceq + IL_0028: ldc.i4.0 + IL_0029: ceq + IL_002b: stloc.3 + IL_002c: ldloc.3 + IL_002d: brtrue.s IL_0007 + + IL_002f: ret + } // end of method NoPropertiesAndEvents::add_MyEvent + + .method public hidebysig specialname instance void + remove_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + // Code size 48 (0x30) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2, + bool V_3) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: ceq + IL_0028: ldc.i4.0 + IL_0029: ceq + IL_002b: stloc.3 + IL_002c: ldloc.3 + IL_002d: brtrue.s IL_0007 + + IL_002f: ret + } // end of method NoPropertiesAndEvents::remove_MyEvent + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method NoPropertiesAndEvents::.ctor + + .event [mscorlib]System.EventHandler MyEvent + { + .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::add_MyEvent(class [mscorlib]System.EventHandler) + .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::remove_MyEvent(class [mscorlib]System.EventHandler) + } // end of event NoPropertiesAndEvents::MyEvent +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.opt.il new file mode 100644 index 0000000000..dbf8140aa2 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.opt.il @@ -0,0 +1,124 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly tmp8FB +{ + .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.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module tmp8FB.tmp +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents + extends [mscorlib]System.Object +{ + .field private class [mscorlib]System.EventHandler MyEvent + .method public hidebysig specialname instance void + add_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method NoPropertiesAndEvents::add_MyEvent + + .method public hidebysig specialname instance void + remove_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method NoPropertiesAndEvents::remove_MyEvent + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method NoPropertiesAndEvents::.ctor + + .event [mscorlib]System.EventHandler MyEvent + { + .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::add_MyEvent(class [mscorlib]System.EventHandler) + .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::remove_MyEvent(class [mscorlib]System.EventHandler) + } // end of event NoPropertiesAndEvents::MyEvent +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.opt.roslyn.il new file mode 100644 index 0000000000..754e2a1eaa --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.opt.roslyn.il @@ -0,0 +1,131 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly tmp8F9 +{ + .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.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module tmp8F9.tmp +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents + extends [mscorlib]System.Object +{ + .field private class [mscorlib]System.EventHandler MyEvent + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname instance void + add_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method NoPropertiesAndEvents::add_MyEvent + + .method public hidebysig specialname instance void + remove_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method NoPropertiesAndEvents::remove_MyEvent + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method NoPropertiesAndEvents::.ctor + + .event [mscorlib]System.EventHandler MyEvent + { + .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::add_MyEvent(class [mscorlib]System.EventHandler) + .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::remove_MyEvent(class [mscorlib]System.EventHandler) + } // end of event NoPropertiesAndEvents::MyEvent +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.roslyn.il new file mode 100644 index 0000000000..0538d65dec --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.roslyn.il @@ -0,0 +1,133 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly tmp8F8 +{ + .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.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module tmp8F8.tmp +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents + extends [mscorlib]System.Object +{ + .field private class [mscorlib]System.EventHandler MyEvent + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method public hidebysig specialname instance void + add_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method NoPropertiesAndEvents::add_MyEvent + + .method public hidebysig specialname instance void + remove_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method NoPropertiesAndEvents::remove_MyEvent + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method NoPropertiesAndEvents::.ctor + + .event [mscorlib]System.EventHandler MyEvent + { + .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::add_MyEvent(class [mscorlib]System.EventHandler) + .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::remove_MyEvent(class [mscorlib]System.EventHandler) + } // end of event NoPropertiesAndEvents::MyEvent +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs b/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs index d9df73458a..d475afd6d4 100644 --- a/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs @@ -110,6 +110,15 @@ public void NoLocalFunctions([ValueSource(nameof(roslynOnlyOptions))] CompilerOp RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings(CSharp.LanguageVersion.CSharp1)); } + [Test] + public void NoPropertiesAndEvents([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) + { + RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { + AutomaticEvents = false, + AutomaticProperties = false, + }); + } + [Test] public void AggressiveScalarReplacementOfAggregates([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 264361f637..6786707c70 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -340,6 +340,10 @@ bool IsAmbiguousAccess(out MemberResolveResult result) } else { + // the field reference is still ambiguous, however, mrr might refer to a different member, + // e.g., in the case of auto events, their backing fields have the same name. + // "this.Event" is ambiguous, but should refer to the field, not the event. + mrr = null; break; } }