From 5150cdce2504677d0179554f503c5eba1ea0381c Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Tue, 22 Nov 2016 19:38:31 +0100 Subject: [PATCH] Improve handling of short-circuiting operators. --- .../CSharp/ExpressionBuilder.cs | 46 +- .../IL/ControlFlow/ConditionDetection.cs | 5 + .../IL/InstructionOutputExtensions.cs | 2 +- .../IL/Instructions/IfInstruction.cs | 14 +- .../IL/Instructions/PatternMatching.cs | 38 +- .../IL/Transforms/ExpressionTransforms.cs | 40 +- .../Tests/ICSharpCode.Decompiler.Tests.csproj | 1 + .../Tests/PrettyTestRunner.cs | 43 +- .../Tests/TestCases/Pretty/ShortCircuit.cs | 100 +++++ .../Tests/TestCases/Pretty/ShortCircuit.il | 398 ++++++++++++++++++ .../TestCases/Pretty/ShortCircuit.opt.il | 300 +++++++++++++ NRefactory | 2 +- 12 files changed, 922 insertions(+), 67 deletions(-) create mode 100644 ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.cs create mode 100644 ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.il create mode 100644 ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.opt.il diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 62d3f1c16..cc8c30bc7 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1464,35 +1464,31 @@ namespace ICSharpCode.Decompiler.CSharp protected internal override TranslatedExpression VisitIfInstruction(IfInstruction inst, TranslationContext context) { + var condition = TranslateCondition(inst.Condition); + var trueBranch = Translate(inst.TrueInst); var falseBranch = Translate(inst.FalseInst); - if (falseBranch.Type.IsKnownType(KnownTypeCode.Boolean)) { - if (inst.TrueInst.MatchLdcI4(1)) { - // "a ? true : b" ==> "a || b" - return new BinaryOperatorExpression( - TranslateCondition(inst.Condition), - BinaryOperatorType.ConditionalOr, - falseBranch) - .WithILInstruction(inst) - .WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Boolean))); - } else if (inst.TrueInst.MatchLdcI4(0)) { - // "!a ? false : b" ==> "a && b" - ILInstruction conditionInst; - Expression conditionExpr; - if (inst.Condition.MatchLogicNot(out conditionInst)) { - conditionExpr = TranslateCondition(conditionInst); - } else { - conditionExpr = LogicNot(TranslateCondition(inst.Condition)); - } - return new BinaryOperatorExpression( - conditionExpr, - BinaryOperatorType.ConditionalAnd, - falseBranch) + + ILInstruction lhsInst, rhsInst; + BinaryOperatorType op = BinaryOperatorType.Any; + TranslatedExpression rhs = default(TranslatedExpression); + if (inst.MatchLogicAnd(out lhsInst, out rhsInst)) { + op = BinaryOperatorType.ConditionalAnd; + Debug.Assert(rhsInst == inst.TrueInst); + rhs = trueBranch; + } else if (inst.MatchLogicOr(out lhsInst, out rhsInst)) { + op = BinaryOperatorType.ConditionalOr; + Debug.Assert(rhsInst == inst.FalseInst); + rhs = falseBranch; + } + // ILAst LogicAnd/LogicOr can return a different value than 0 or 1 + // if the rhs is evaluated. + // We can only correctly translate it to C# if the rhs is of type boolean: + if (op != BinaryOperatorType.Any && rhs.Type.IsKnownType(KnownTypeCode.Boolean)) { + return new BinaryOperatorExpression(condition, op, rhs) .WithILInstruction(inst) .WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Boolean))); - } } - var condition = TranslateCondition(inst.Condition); - var trueBranch = Translate(inst.TrueInst); + IType targetType; if (!trueBranch.Type.Equals(SpecialType.NullType) && !falseBranch.Type.Equals(SpecialType.NullType) && !trueBranch.Type.Equals(falseBranch.Type)) { targetType = compilation.FindType(inst.ResultType.ToKnownTypeCode()); diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs index cef23f7bd..36f63dbec 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs @@ -141,6 +141,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow // -> "if (... && !nestedCondition) { ... } goto exitPoint;" ifInst.Condition = IfInstruction.LogicAnd(ifInst.Condition, new LogicNot(nestedCondition)); targetBlock.Instructions.RemoveAt(0); + // Update targetBlock label now that we've removed the first instruction + if (targetBlock.Instructions.FirstOrDefault()?.ILRange.IsEmpty == false) { + int offset = targetBlock.Instructions[0].ILRange.Start; + targetBlock.ILRange = new Interval(offset, offset); + } } } diff --git a/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs b/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs index 86c3fe686..311be0419 100644 --- a/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs +++ b/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs @@ -50,7 +50,7 @@ namespace ICSharpCode.Decompiler.IL public static void WriteTo(this ISymbol symbol, ITextOutput output) { - output.WriteReference(symbol.ToString(), symbol); + output.WriteReference(symbol.Name, symbol); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs index 7937a38f1..ed7e87441 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs @@ -32,7 +32,7 @@ namespace ICSharpCode.Decompiler.IL /// /// IfInstruction is also used to represent logical operators: /// "a || b" ==> if (a) (ldc.i4 1) else (b) - /// "a && b" ==> if (logic.not(a)) (ldc.i4 0) else (b) + /// "a && b" ==> if (a) (b) else (ldc.i4 0) /// "a ? b : c" ==> if (a) (b) else (c) /// partial class IfInstruction : ILInstruction @@ -46,20 +46,12 @@ namespace ICSharpCode.Decompiler.IL public static IfInstruction LogicAnd(ILInstruction lhs, ILInstruction rhs) { - return new IfInstruction( - new LogicNot(lhs), - new LdcI4(0), - rhs - ); + return new IfInstruction(lhs, rhs, new LdcI4(0)); } public static IfInstruction LogicOr(ILInstruction lhs, ILInstruction rhs) { - return new IfInstruction( - lhs, - new LdcI4(1), - rhs - ); + return new IfInstruction(lhs, new LdcI4(1), rhs); } internal override void CheckInvariant(ILPhase phase) diff --git a/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs b/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs index d4113d11c..d891035b7 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs @@ -143,7 +143,43 @@ namespace ICSharpCode.Decompiler.IL trueInst = null; return false; } - + + /// + /// Matches a 'logic and' instruction ("if (a) b else ldc.i4 0"). + /// Note: unlike C# '&&', this instruction is not limited to booleans, + /// but allows passing through arbitrary I4 values on the rhs (but not on the lhs). + /// + public bool MatchLogicAnd(out ILInstruction lhs, out ILInstruction rhs) + { + var inst = this as IfInstruction; + if (inst != null && inst.FalseInst.MatchLdcI4(0)) { + lhs = inst.Condition; + rhs = inst.TrueInst; + return true; + } + lhs = null; + rhs = null; + return false; + } + + /// + /// Matches a 'logic or' instruction ("if (a) ldc.i4 1 else b"). + /// Note: unlike C# '||', this instruction is not limited to booleans, + /// but allows passing through arbitrary I4 values on the rhs (but not on the lhs). + /// + public bool MatchLogicOr(out ILInstruction lhs, out ILInstruction rhs) + { + var inst = this as IfInstruction; + if (inst != null && inst.TrueInst.MatchLdcI4(1)) { + lhs = inst.Condition; + rhs = inst.FalseInst; + return true; + } + lhs = null; + rhs = null; + return false; + } + public bool MatchTryCatchHandler(out ILVariable variable) { var inst = this as TryCatchHandler; diff --git a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs index d8665d7f7..f0216a6e0 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs @@ -104,7 +104,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms protected internal override void VisitLogicNot(LogicNot inst) { - ILInstruction arg; + ILInstruction arg, lhs, rhs; if (inst.Argument.MatchLogicNot(out arg)) { // logic.not(logic.not(arg)) // ==> arg @@ -124,14 +124,27 @@ namespace ICSharpCode.Decompiler.IL.Transforms stepper.Stepped(); } comp.AcceptVisitor(this); - } else if (inst.Argument is IfInstruction && ((IfInstruction)inst.Argument).TrueInst is LdcI4) { - // Likely a logic and/or: - // logic.not(if (a) (ldc.i4 val) (c)) - // ==> if (a) (ldc.i4 opposite_val) (logic.not(c)) + } else if (inst.Argument.MatchLogicAnd(out lhs, out rhs)) { + // logic.not(if (lhs) rhs else ldc.i4 0) + // ==> if (logic.not(lhs)) ldc.i4 1 else logic.not(rhs) IfInstruction ifInst = (IfInstruction)inst.Argument; - LdcI4 trueInst = (LdcI4)ifInst.TrueInst; - ifInst.TrueInst = new LdcI4(trueInst.Value != 0 ? 0 : 1) { ILRange = trueInst.ILRange }; - ifInst.FalseInst = new LogicNot(ifInst.FalseInst) { ILRange = inst.ILRange }; + var ldc0 = ifInst.FalseInst; + Debug.Assert(ldc0.MatchLdcI4(0)); + ifInst.Condition = new LogicNot(lhs) { ILRange = inst.ILRange }; + ifInst.TrueInst = new LdcI4(1) { ILRange = ldc0.ILRange }; + ifInst.FalseInst = new LogicNot(rhs) { ILRange = inst.ILRange }; + inst.ReplaceWith(ifInst); + stepper.Stepped(); + ifInst.AcceptVisitor(this); + } else if (inst.Argument.MatchLogicOr(out lhs, out rhs)) { + // logic.not(if (lhs) ldc.i4 1 else rhs) + // ==> if (logic.not(lhs)) logic.not(rhs) else ldc.i4 0) + IfInstruction ifInst = (IfInstruction)inst.Argument; + var ldc1 = ifInst.TrueInst; + Debug.Assert(ldc1.MatchLdcI4(1)); + ifInst.Condition = new LogicNot(lhs) { ILRange = inst.ILRange }; + ifInst.TrueInst = new LogicNot(rhs) { ILRange = inst.ILRange }; + ifInst.FalseInst = new LdcI4(0) { ILRange = ldc1.ILRange }; inst.ReplaceWith(ifInst); stepper.Stepped(); ifInst.AcceptVisitor(this); @@ -226,7 +239,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms protected internal override void VisitIfInstruction(IfInstruction inst) { + // Bring LogicAnd/LogicOr into their canonical forms: + // if (cond) ldc.i4 0 else RHS --> if (!cond) RHS else ldc.i4 0 + // if (cond) RHS else ldc.i4 1 --> if (!cond) ldc.i4 1 else RHS + if (inst.TrueInst.MatchLdcI4(0) || inst.FalseInst.MatchLdcI4(1)) { + var t = inst.TrueInst; + inst.TrueInst = inst.FalseInst; + inst.FalseInst = t; + inst.Condition = new LogicNot(inst.Condition); + } + base.VisitIfInstruction(inst); + // if (cond) stloc (A, V1) else stloc (A, V2) --> stloc (A, if (cond) V1 else V2) Block trueInst = inst.TrueInst as Block; if (trueInst == null || trueInst.Instructions.Count != 1) diff --git a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj index b4f494929..c221bd974 100644 --- a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj @@ -137,6 +137,7 @@ + diff --git a/ICSharpCode.Decompiler/Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler/Tests/PrettyTestRunner.cs index 1f3a69bd5..dace3a8a6 100644 --- a/ICSharpCode.Decompiler/Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler/Tests/PrettyTestRunner.cs @@ -43,7 +43,7 @@ namespace ICSharpCode.Decompiler.Tests foreach (var file in new DirectoryInfo(TestCasePath).EnumerateFiles()) { if (file.Extension == ".txt" || file.Extension == ".exe") continue; - var testName = Path.GetFileNameWithoutExtension(file.Name); + var testName = file.Name.Split('.')[0]; Assert.Contains(testName, testNames); } } @@ -68,38 +68,41 @@ namespace ICSharpCode.Decompiler.Tests Run(); Run(asmOptions: AssemblerOptions.UseDebug); } - + [Test] - public void ShortCircuit() + public void ShortCircuit([Values(CompilerOptions.None, CompilerOptions.Optimize)] CompilerOptions cscOptions) { - Run(); - Run(asmOptions: AssemblerOptions.UseDebug); + Run(cscOptions: cscOptions); } - void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None) + void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None) { - var ilFile = Path.Combine(TestCasePath, testName + ".il"); + var ilFile = Path.Combine(TestCasePath, testName); + if ((cscOptions & CompilerOptions.Optimize) != 0) + ilFile += ".opt"; + if ((cscOptions & CompilerOptions.Force32Bit) != 0) + ilFile += ".32"; + if ((cscOptions & CompilerOptions.UseDebug) != 0) + ilFile += ".dbg"; + ilFile += ".il"; var csFile = Path.Combine(TestCasePath, testName + ".cs"); - EnsureSourceFilesExist(Path.Combine(TestCasePath, testName)); - - var executable = Tester.AssembleIL(ilFile, asmOptions | AssemblerOptions.Library); - var decompiled = Tester.DecompileCSharp(executable); - - CodeAssert.FilesAreEqual(csFile, decompiled); - } - - void EnsureSourceFilesExist(string fileName) - { - if (!File.Exists(fileName + ".il")) { + + if (!File.Exists(ilFile)) { + // re-create .il file if necessary CompilerResults output = null; try { - output = Tester.CompileCSharp(fileName + ".cs", CompilerOptions.None); - Tester.Disassemble(output.PathToAssembly, fileName + ".il"); + output = Tester.CompileCSharp(csFile, cscOptions | CompilerOptions.Library); + Tester.Disassemble(output.PathToAssembly, ilFile); } finally { if (output != null) output.TempFiles.Delete(); } } + + var executable = Tester.AssembleIL(ilFile, asmOptions | AssemblerOptions.Library); + var decompiled = Tester.DecompileCSharp(executable); + + CodeAssert.FilesAreEqual(csFile, decompiled); } } } diff --git a/ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.cs b/ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.cs new file mode 100644 index 000000000..2c53058b9 --- /dev/null +++ b/ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.cs @@ -0,0 +1,100 @@ +// 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. + +// compile: +// csc ShortCircuit.cs /t:Library && ildasm /text ShortCircuit.dll >ShortCircuit.il +// csc ShortCircuit.cs /t:Library /o /out:ShortCircuit.opt.dll && ildasm /text ShortCircuit.opt.dll >ShortCircuit.opt.il + +using System; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty +{ + public abstract class ShortCircuit + { + public abstract void B(bool b); + public abstract bool F(int i); + public abstract void M1(); + public abstract void M2(); + public abstract void E(); + + public void ExprAnd() + { + this.B(this.F(0) && this.F(1)); + } + + public void ExprOr() + { + this.B(this.F(0) || this.F(1)); + } + + public void ExprCond() + { + this.B(this.F(0) ? this.F(1) : this.F(2)); + } + + public void StmtAnd2() + { + if (this.F(0) && this.F(1)) { + this.M1(); + } else { + this.M2(); + } + this.E(); + } + + public void StmtOr2() + { + if (this.F(0) || this.F(1)) { + this.M1(); + } else { + this.M2(); + } + this.E(); + } + + public void StmtAnd3() + { + if (this.F(0) && this.F(1) && this.F(2)) { + this.M1(); + } else { + this.M2(); + } + this.E(); + } + + public void StmtOr3() + { + if (this.F(0) || this.F(1) || this.F(3)) { + this.M1(); + } else { + this.M2(); + } + this.E(); + } + + public void StmtComplex() + { + if (this.F(0) && this.F(1) && !this.F(2) && (this.F(3) || this.F(4))) { + this.M1(); + } else { + this.M2(); + } + this.E(); + } + } +} diff --git a/ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.il b/ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.il new file mode 100644 index 000000000..46a3e47bd --- /dev/null +++ b/ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.il @@ -0,0 +1,398 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.18020 +// Copyright (c) Microsoft Corporation. All rights reserved. + + + +// 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 '0hc4wf1j' +{ + .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 '0hc4wf1j.dll' +// MVID: {BB9907D8-9A9B-40EA-99C2-170F6DA15820} +.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: 0x017B0000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public abstract auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit + extends [mscorlib]System.Object +{ + .method public hidebysig newslot abstract virtual + instance void B(bool b) cil managed + { + } // end of method ShortCircuit::B + + .method public hidebysig newslot abstract virtual + instance bool F(int32 i) cil managed + { + } // end of method ShortCircuit::F + + .method public hidebysig newslot abstract virtual + instance void M1() cil managed + { + } // end of method ShortCircuit::M1 + + .method public hidebysig newslot abstract virtual + instance void M2() cil managed + { + } // end of method ShortCircuit::M2 + + .method public hidebysig newslot abstract virtual + instance void E() cil managed + { + } // end of method ShortCircuit::E + + .method public hidebysig instance void + ExprAnd() cil managed + { + // Code size 29 (0x1d) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.0 + IL_0003: ldc.i4.0 + IL_0004: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0009: brfalse.s IL_0014 + + IL_000b: ldarg.0 + IL_000c: ldc.i4.1 + IL_000d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0012: br.s IL_0015 + + IL_0014: ldc.i4.0 + IL_0015: nop + IL_0016: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool) + IL_001b: nop + IL_001c: ret + } // end of method ShortCircuit::ExprAnd + + .method public hidebysig instance void + ExprOr() cil managed + { + // Code size 29 (0x1d) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.0 + IL_0003: ldc.i4.0 + IL_0004: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0009: brtrue.s IL_0014 + + IL_000b: ldarg.0 + IL_000c: ldc.i4.1 + IL_000d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0012: br.s IL_0015 + + IL_0014: ldc.i4.1 + IL_0015: nop + IL_0016: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool) + IL_001b: nop + IL_001c: ret + } // end of method ShortCircuit::ExprOr + + .method public hidebysig instance void + ExprCond() cil managed + { + // Code size 35 (0x23) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.0 + IL_0003: ldc.i4.0 + IL_0004: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0009: brtrue.s IL_0014 + + IL_000b: ldarg.0 + IL_000c: ldc.i4.2 + IL_000d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0012: br.s IL_001b + + IL_0014: ldarg.0 + IL_0015: ldc.i4.1 + IL_0016: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_001b: nop + IL_001c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool) + IL_0021: nop + IL_0022: ret + } // end of method ShortCircuit::ExprCond + + .method public hidebysig instance void + StmtAnd2() cil managed + { + // Code size 56 (0x38) + .maxstack 2 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0008: brfalse.s IL_0016 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0011: ldc.i4.0 + IL_0012: ceq + IL_0014: br.s IL_0017 + + IL_0016: ldc.i4.1 + IL_0017: nop + IL_0018: stloc.0 + IL_0019: ldloc.0 + IL_001a: brtrue.s IL_0027 + + IL_001c: nop + IL_001d: ldarg.0 + IL_001e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0023: nop + IL_0024: nop + IL_0025: br.s IL_0030 + + IL_0027: nop + IL_0028: ldarg.0 + IL_0029: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_002e: nop + IL_002f: nop + IL_0030: ldarg.0 + IL_0031: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_0036: nop + IL_0037: ret + } // end of method ShortCircuit::StmtAnd2 + + .method public hidebysig instance void + StmtOr2() cil managed + { + // Code size 56 (0x38) + .maxstack 2 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0008: brtrue.s IL_0016 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0011: ldc.i4.0 + IL_0012: ceq + IL_0014: br.s IL_0017 + + IL_0016: ldc.i4.0 + IL_0017: nop + IL_0018: stloc.0 + IL_0019: ldloc.0 + IL_001a: brtrue.s IL_0027 + + IL_001c: nop + IL_001d: ldarg.0 + IL_001e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0023: nop + IL_0024: nop + IL_0025: br.s IL_0030 + + IL_0027: nop + IL_0028: ldarg.0 + IL_0029: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_002e: nop + IL_002f: nop + IL_0030: ldarg.0 + IL_0031: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_0036: nop + IL_0037: ret + } // end of method ShortCircuit::StmtOr2 + + .method public hidebysig instance void + StmtAnd3() cil managed + { + // Code size 65 (0x41) + .maxstack 2 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0008: brfalse.s IL_001f + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0011: brfalse.s IL_001f + + IL_0013: ldarg.0 + IL_0014: ldc.i4.2 + IL_0015: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_001a: ldc.i4.0 + IL_001b: ceq + IL_001d: br.s IL_0020 + + IL_001f: ldc.i4.1 + IL_0020: nop + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: brtrue.s IL_0030 + + IL_0025: nop + IL_0026: ldarg.0 + IL_0027: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_002c: nop + IL_002d: nop + IL_002e: br.s IL_0039 + + IL_0030: nop + IL_0031: ldarg.0 + IL_0032: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_0037: nop + IL_0038: nop + IL_0039: ldarg.0 + IL_003a: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_003f: nop + IL_0040: ret + } // end of method ShortCircuit::StmtAnd3 + + .method public hidebysig instance void + StmtOr3() cil managed + { + // Code size 65 (0x41) + .maxstack 2 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0008: brtrue.s IL_001f + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0011: brtrue.s IL_001f + + IL_0013: ldarg.0 + IL_0014: ldc.i4.3 + IL_0015: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_001a: ldc.i4.0 + IL_001b: ceq + IL_001d: br.s IL_0020 + + IL_001f: ldc.i4.0 + IL_0020: nop + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: brtrue.s IL_0030 + + IL_0025: nop + IL_0026: ldarg.0 + IL_0027: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_002c: nop + IL_002d: nop + IL_002e: br.s IL_0039 + + IL_0030: nop + IL_0031: ldarg.0 + IL_0032: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_0037: nop + IL_0038: nop + IL_0039: ldarg.0 + IL_003a: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_003f: nop + IL_0040: ret + } // end of method ShortCircuit::StmtOr3 + + .method public hidebysig instance void + StmtComplex() cil managed + { + // Code size 87 (0x57) + .maxstack 2 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0008: brfalse.s IL_0035 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0011: brfalse.s IL_0035 + + IL_0013: ldarg.0 + IL_0014: ldc.i4.2 + IL_0015: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_001a: brtrue.s IL_0035 + + IL_001c: ldarg.0 + IL_001d: ldc.i4.3 + IL_001e: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0023: brtrue.s IL_0031 + + IL_0025: ldarg.0 + IL_0026: ldc.i4.4 + IL_0027: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_002c: ldc.i4.0 + IL_002d: ceq + IL_002f: br.s IL_0032 + + IL_0031: ldc.i4.0 + IL_0032: nop + IL_0033: br.s IL_0036 + + IL_0035: ldc.i4.1 + IL_0036: nop + IL_0037: stloc.0 + IL_0038: ldloc.0 + IL_0039: brtrue.s IL_0046 + + IL_003b: nop + IL_003c: ldarg.0 + IL_003d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0042: nop + IL_0043: nop + IL_0044: br.s IL_004f + + IL_0046: nop + IL_0047: ldarg.0 + IL_0048: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_004d: nop + IL_004e: nop + IL_004f: ldarg.0 + IL_0050: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_0055: nop + IL_0056: ret + } // end of method ShortCircuit::StmtComplex + + .method family 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 ShortCircuit::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file ../../Tests/TestCases/Pretty\ShortCircuit.res diff --git a/ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.opt.il b/ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.opt.il new file mode 100644 index 000000000..f76586cdb --- /dev/null +++ b/ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.opt.il @@ -0,0 +1,300 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. All rights reserved. + + + +// 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 ShortCircuit.opt +{ + .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 ) + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module ShortCircuit.opt.dll +// MVID: {B2A8B996-539C-419F-B01A-1DC6A75F40BA} +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x00C70000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public abstract auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit + extends [mscorlib]System.Object +{ + .method public hidebysig newslot abstract virtual + instance void B(bool b) cil managed + { + } // end of method ShortCircuit::B + + .method public hidebysig newslot abstract virtual + instance bool F(int32 i) cil managed + { + } // end of method ShortCircuit::F + + .method public hidebysig newslot abstract virtual + instance void M1() cil managed + { + } // end of method ShortCircuit::M1 + + .method public hidebysig newslot abstract virtual + instance void M2() cil managed + { + } // end of method ShortCircuit::M2 + + .method public hidebysig newslot abstract virtual + instance void E() cil managed + { + } // end of method ShortCircuit::E + + .method public hidebysig instance void + ExprAnd() cil managed + { + // Code size 26 (0x1a) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0008: brfalse.s IL_0013 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0011: br.s IL_0014 + + IL_0013: ldc.i4.0 + IL_0014: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool) + IL_0019: ret + } // end of method ShortCircuit::ExprAnd + + .method public hidebysig instance void + ExprOr() cil managed + { + // Code size 26 (0x1a) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0008: brtrue.s IL_0013 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0011: br.s IL_0014 + + IL_0013: ldc.i4.1 + IL_0014: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool) + IL_0019: ret + } // end of method ShortCircuit::ExprOr + + .method public hidebysig instance void + ExprCond() cil managed + { + // Code size 32 (0x20) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0008: brtrue.s IL_0013 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.2 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0011: br.s IL_001a + + IL_0013: ldarg.0 + IL_0014: ldc.i4.1 + IL_0015: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_001a: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool) + IL_001f: ret + } // end of method ShortCircuit::ExprCond + + .method public hidebysig instance void + StmtAnd2() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0007: brfalse.s IL_001a + + IL_0009: ldarg.0 + IL_000a: ldc.i4.1 + IL_000b: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0010: brfalse.s IL_001a + + IL_0012: ldarg.0 + IL_0013: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0018: br.s IL_0020 + + IL_001a: ldarg.0 + IL_001b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_0020: ldarg.0 + IL_0021: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_0026: ret + } // end of method ShortCircuit::StmtAnd2 + + .method public hidebysig instance void + StmtOr2() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0007: brtrue.s IL_0012 + + IL_0009: ldarg.0 + IL_000a: ldc.i4.1 + IL_000b: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0010: brfalse.s IL_001a + + IL_0012: ldarg.0 + IL_0013: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0018: br.s IL_0020 + + IL_001a: ldarg.0 + IL_001b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_0020: ldarg.0 + IL_0021: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_0026: ret + } // end of method ShortCircuit::StmtOr2 + + .method public hidebysig instance void + StmtAnd3() cil managed + { + // Code size 48 (0x30) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0007: brfalse.s IL_0023 + + IL_0009: ldarg.0 + IL_000a: ldc.i4.1 + IL_000b: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0010: brfalse.s IL_0023 + + IL_0012: ldarg.0 + IL_0013: ldc.i4.2 + IL_0014: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0019: brfalse.s IL_0023 + + IL_001b: ldarg.0 + IL_001c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0021: br.s IL_0029 + + IL_0023: ldarg.0 + IL_0024: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_0029: ldarg.0 + IL_002a: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_002f: ret + } // end of method ShortCircuit::StmtAnd3 + + .method public hidebysig instance void + StmtOr3() cil managed + { + // Code size 48 (0x30) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0007: brtrue.s IL_001b + + IL_0009: ldarg.0 + IL_000a: ldc.i4.1 + IL_000b: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0010: brtrue.s IL_001b + + IL_0012: ldarg.0 + IL_0013: ldc.i4.3 + IL_0014: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0019: brfalse.s IL_0023 + + IL_001b: ldarg.0 + IL_001c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0021: br.s IL_0029 + + IL_0023: ldarg.0 + IL_0024: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_0029: ldarg.0 + IL_002a: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_002f: ret + } // end of method ShortCircuit::StmtOr3 + + .method public hidebysig instance void + StmtComplex() cil managed + { + // Code size 66 (0x42) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0007: brfalse.s IL_0035 + + IL_0009: ldarg.0 + IL_000a: ldc.i4.1 + IL_000b: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0010: brfalse.s IL_0035 + + IL_0012: ldarg.0 + IL_0013: ldc.i4.2 + IL_0014: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0019: brtrue.s IL_0035 + + IL_001b: ldarg.0 + IL_001c: ldc.i4.3 + IL_001d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_0022: brtrue.s IL_002d + + IL_0024: ldarg.0 + IL_0025: ldc.i4.4 + IL_0026: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32) + IL_002b: brfalse.s IL_0035 + + IL_002d: ldarg.0 + IL_002e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0033: br.s IL_003b + + IL_0035: ldarg.0 + IL_0036: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_003b: ldarg.0 + IL_003c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_0041: ret + } // end of method ShortCircuit::StmtComplex + + .method family 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 ShortCircuit::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/NRefactory b/NRefactory index 89ef97065..85cf91fe5 160000 --- a/NRefactory +++ b/NRefactory @@ -1 +1 @@ -Subproject commit 89ef9706523059f0a39b04b15ebcd4dea87e0e08 +Subproject commit 85cf91fe5138252a44b8e1d14a10366f90a5a10d