Browse Source

Merge branch '5.0.x' of https://github.com/icsharpcode/ILSpy

pull/1725/head
Siegfried Pammer 6 years ago
parent
commit
a89111b914
  1. 2
      BuildTools/appveyor-install.ps1
  2. 2
      BuildTools/pipelines-install.ps1
  3. 2
      BuildTools/update-assemblyinfo.ps1
  4. 2
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  5. 17
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/FloatingPointArithmetic.cs
  6. 18
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Async.cs
  7. 4
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomTaskType.cs
  8. 23
      ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.Expected.cs
  9. 17
      ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.cs
  10. 69
      ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.opt.roslyn.il
  11. 81
      ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.roslyn.il
  12. 8
      ICSharpCode.Decompiler.Tests/UglyTestRunner.cs
  13. 32
      ICSharpCode.Decompiler/CSharp/CallBuilder.cs
  14. 16
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  15. 22
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  16. 32
      ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs
  17. 10
      ILSpy/MainWindow.xaml.cs
  18. 2
      ILSpy/Properties/AssemblyInfo.template.cs
  19. 1
      appveyor.yml
  20. 5
      azure-pipelines.yml

2
BuildTools/appveyor-install.ps1

@ -4,7 +4,7 @@ $baseCommit = "d779383cb85003d6dabeb976f0845631e07bf463"; @@ -4,7 +4,7 @@ $baseCommit = "d779383cb85003d6dabeb976f0845631e07bf463";
$baseCommitRev = 1;
# make sure this list matches artifacts-only branches list in appveyor.yml!
$masterBranches = @("master", "3.2.x");
$masterBranches = @("master", "5.0.x");
$globalAssemblyInfoTemplateFile = "ILSpy/Properties/AssemblyInfo.template.cs";

2
BuildTools/pipelines-install.ps1

@ -4,7 +4,7 @@ $baseCommit = "d779383cb85003d6dabeb976f0845631e07bf463"; @@ -4,7 +4,7 @@ $baseCommit = "d779383cb85003d6dabeb976f0845631e07bf463";
$baseCommitRev = 1;
# make sure this list matches artifacts-only branches list in azure-pipelines.yml!
$masterBranches = @("master", "3.2.x");
$masterBranches = @("master", "5.0.x");
$globalAssemblyInfoTemplateFile = "ILSpy/Properties/AssemblyInfo.template.cs";

2
BuildTools/update-assemblyinfo.ps1

@ -4,7 +4,7 @@ $baseCommit = "d779383cb85003d6dabeb976f0845631e07bf463"; @@ -4,7 +4,7 @@ $baseCommit = "d779383cb85003d6dabeb976f0845631e07bf463";
$baseCommitRev = 1;
# make sure this list matches artifacts-only branches list in appveyor.yml!
$masterBranches = @("master", "3.2.x");
$masterBranches = @("master", "5.0.x");
$globalAssemblyInfoTemplateFile = "ILSpy/Properties/AssemblyInfo.template.cs";

2
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -82,6 +82,8 @@ @@ -82,6 +82,8 @@
<Compile Include="TestCases\ILPretty\ConstantBlobs.cs" />
<Compile Include="TestCases\Pretty\OutVariables.cs" />
<Compile Include="TestCases\Pretty\CustomTaskType.cs" />
<None Include="TestCases\Ugly\NoExtensionMethods.Expected.cs" />
<Compile Include="TestCases\Ugly\NoExtensionMethods.cs" />
<None Include="TestCases\VBPretty\VBCompoundAssign.cs" />
<Compile Include="TestCases\Pretty\ThrowExpressions.cs" />
<None Include="TestCases\ILPretty\Issue1145.cs" />

17
ICSharpCode.Decompiler.Tests/TestCases/Correctness/FloatingPointArithmetic.cs

@ -7,6 +7,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -7,6 +7,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
public static int Main(string[] args)
{
Issue999();
Issue1656();
return 0;
}
@ -20,5 +21,21 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -20,5 +21,21 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
{
return 0.99f * v + 0.01f;
}
static void Issue1656()
{
double primary = 'B';
CxAssert((++primary) == 'C');
CxAssert((--primary) == 'B');
CxAssert((primary++) == 'B');
CxAssert((primary--) == 'C');
}
static void CxAssert(bool v)
{
if (!v) {
throw new InvalidOperationException();
}
}
}
}

18
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Async.cs

@ -167,6 +167,24 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -167,6 +167,24 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
};
}
public static async Task AlwaysThrow()
{
throw null;
}
public static async Task InfiniteLoop()
{
while (true) {
}
}
public static async Task InfiniteLoopWithAwait()
{
while (true) {
await Task.Delay(10);
}
}
#if CS70
public static async Task<int> AsyncLocalFunctions()
{

4
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomTaskType.cs

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
using System;
#pragma warning disable 1998
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

23
ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.Expected.cs

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
using System;
using System.Runtime.CompilerServices;
[assembly: Extension]
namespace ICSharpCode.Decompiler.Tests.TestCases.Ugly
{
[Extension]
internal static class NoExtensionMethods
{
[Extension]
internal static Func<T> AsFunc<T>(T value) where T : class
{
return new Func<T>(value, __ldftn(Return));
}
[Extension]
private static T Return<T>(T value)
{
return value;
}
}
}

17
ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.cs

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
using System;
namespace ICSharpCode.Decompiler.Tests.TestCases.Ugly
{
internal static class NoExtensionMethods
{
internal static Func<T> AsFunc<T>(this T value) where T : class
{
return new Func<T>(value.Return);
}
private static T Return<T>(this T value)
{
return value;
}
}
}

69
ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.opt.roslyn.il

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
// 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 NoExtensionMethods
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
.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 NoExtensionMethods.dll
.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 abstract auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
.method assembly hidebysig static class [mscorlib]System.Func`1<!!T>
AsFunc<class T>(!!T 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
// Code size 18 (0x12)
.maxstack 8
IL_0000: ldarg.0
IL_0001: box !!T
IL_0006: ldftn !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<!!0>(!!0)
IL_000c: newobj instance void class [mscorlib]System.Func`1<!!T>::.ctor(object,
native int)
IL_0011: ret
} // end of method NoExtensionMethods::AsFunc
.method private hidebysig static !!T Return<T>(!!T 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ret
} // end of method NoExtensionMethods::Return
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************

81
ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.roslyn.il

@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
// 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 NoExtensionMethods
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
.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 NoExtensionMethods.dll
.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 abstract auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
.method assembly hidebysig static class [mscorlib]System.Func`1<!!T>
AsFunc<class T>(!!T 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
// Code size 23 (0x17)
.maxstack 2
.locals init (class [mscorlib]System.Func`1<!!T> V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: box !!T
IL_0007: ldftn !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<!!0>(!!0)
IL_000d: newobj instance void class [mscorlib]System.Func`1<!!T>::.ctor(object,
native int)
IL_0012: stloc.0
IL_0013: br.s IL_0015
IL_0015: ldloc.0
IL_0016: ret
} // end of method NoExtensionMethods::AsFunc
.method private hidebysig static !!T Return<T>(!!T 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 1
.locals init (!!T V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
} // end of method NoExtensionMethods::Return
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************

8
ICSharpCode.Decompiler.Tests/UglyTestRunner.cs

@ -83,6 +83,14 @@ namespace ICSharpCode.Decompiler.Tests @@ -83,6 +83,14 @@ namespace ICSharpCode.Decompiler.Tests
});
}
[Test]
public void NoExtensionMethods([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings {
ExtensionMethods = false
});
}
void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)
{
Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, decompilerSettings);

32
ICSharpCode.Decompiler/CSharp/CallBuilder.cs

@ -1235,6 +1235,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1235,6 +1235,11 @@ namespace ICSharpCode.Decompiler.CSharp
default:
throw new ArgumentException($"Unknown instruction type: {func.OpCode}");
}
if (method.IsStatic && !method.IsExtensionMethod) {
var argumentList = BuildArgumentList(expectedTargetDetails, null, inst.Method,
0, inst.Arguments, null);
return HandleConstructorCall(new ExpectedTargetDetails { CallOpCode = OpCode.NewObj }, null, inst.Method, argumentList).WithILInstruction(inst);
}
return HandleDelegateConstruction(inst.Method.DeclaringType, method, expectedTargetDetails, thisArg, inst);
}
@ -1243,9 +1248,15 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1243,9 +1248,15 @@ namespace ICSharpCode.Decompiler.CSharp
return HandleDelegateConstruction(inst.Type, inst.Method, new ExpectedTargetDetails { CallOpCode = OpCode.CallVirt }, inst.Argument, inst);
}
TranslatedExpression HandleDelegateConstruction(IType delegateType, IMethod method, ExpectedTargetDetails expectedTargetDetails, ILInstruction thisArg, ILInstruction inst)
internal ExpressionWithResolveResult BuildMethodReference(IMethod method, bool isVirtual)
{
var expr = BuildDelegateReference(method, invokeMethod: null, new ExpectedTargetDetails { CallOpCode = isVirtual ? OpCode.CallVirt : OpCode.Call }, thisArg: null);
expr.Expression.RemoveAnnotations<ResolveResult>();
return expr.Expression.WithRR(new MemberResolveResult(null, method));
}
ExpressionWithResolveResult BuildDelegateReference(IMethod method, IMethod invokeMethod, ExpectedTargetDetails expectedTargetDetails, ILInstruction thisArg)
{
var invokeMethod = delegateType.GetDelegateInvokeMethod();
TranslatedExpression target;
IType targetType;
bool requireTarget;
@ -1331,27 +1342,32 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1331,27 +1342,32 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
requireTarget = !method.IsLocalFunction && (step & 1) != 0;
Expression targetExpression;
ExpressionWithResolveResult targetExpression;
Debug.Assert(result != null);
if (requireTarget) {
Debug.Assert(target.Expression != null);
var mre = new MemberReferenceExpression(target, methodName);
if ((step & 2) != 0)
mre.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));
mre.WithRR(result);
targetExpression = mre;
targetExpression = mre.WithRR(result);
} else {
var ide = new IdentifierExpression(methodName);
if ((step & 2) != 0)
ide.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));
ide.WithRR(result);
targetExpression = ide;
targetExpression = ide.WithRR(result);
}
return targetExpression;
}
TranslatedExpression HandleDelegateConstruction(IType delegateType, IMethod method, ExpectedTargetDetails expectedTargetDetails, ILInstruction thisArg, ILInstruction inst)
{
var invokeMethod = delegateType.GetDelegateInvokeMethod();
var targetExpression = BuildDelegateReference(method, invokeMethod, expectedTargetDetails, thisArg);
var oce = new ObjectCreateExpression(expressionBuilder.ConvertType(delegateType), targetExpression)
.WithILInstruction(inst)
.WithRR(new ConversionResolveResult(
delegateType,
result,
targetExpression.ResolveResult,
Conversion.MethodGroupConversion(method, expectedTargetDetails.CallOpCode == OpCode.CallVirt, false)));
return oce;
}

16
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -3134,6 +3134,22 @@ namespace ICSharpCode.Decompiler.CSharp @@ -3134,6 +3134,22 @@ namespace ICSharpCode.Decompiler.CSharp
.WithRR(new OperatorResolveResult(SpecialType.Dynamic, inst.Operation, new[] { target.ResolveResult, value.ResolveResult }));
}
protected internal override TranslatedExpression VisitLdFtn(LdFtn inst, TranslationContext context)
{
ExpressionWithResolveResult delegateRef = new CallBuilder(this, typeSystem, settings).BuildMethodReference(inst.Method, isVirtual: false);
return new InvocationExpression(new IdentifierExpression("__ldftn"), delegateRef)
.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.IntPtr)))
.WithILInstruction(inst);
}
protected internal override TranslatedExpression VisitLdVirtFtn(LdVirtFtn inst, TranslationContext context)
{
ExpressionWithResolveResult delegateRef = new CallBuilder(this, typeSystem, settings).BuildMethodReference(inst.Method, isVirtual: true);
return new InvocationExpression(new IdentifierExpression("__ldvirtftn"), delegateRef)
.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.IntPtr)))
.WithILInstruction(inst);
}
protected internal override TranslatedExpression VisitInvalidBranch(InvalidBranch inst, TranslationContext context)
{
string message = "Error";

22
ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs

@ -85,6 +85,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -85,6 +85,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
TryCatch mainTryCatch;
Block setResultAndExitBlock; // block that is jumped to for return statements
int finalState; // final state after the setResultAndExitBlock
bool finalStateKnown;
ILVariable resultVar; // the variable that gets returned by the setResultAndExitBlock
ILVariable doFinallyBodies;
@ -352,7 +353,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -352,7 +353,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
moveNextFunction = YieldReturnDecompiler.CreateILAst(moveNextMethod, context);
if (!(moveNextFunction.Body is BlockContainer blockContainer))
throw new SymbolicAnalysisFailedException();
if (blockContainer.Blocks.Count != 2)
if (blockContainer.Blocks.Count != 2 && blockContainer.Blocks.Count != 1)
throw new SymbolicAnalysisFailedException();
if (blockContainer.EntryPoint.IncomingEdgeCount != 1)
throw new SymbolicAnalysisFailedException();
@ -389,7 +390,14 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -389,7 +390,14 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
doFinallyBodies = initDoFinallyBodies.Variable;
}
setResultAndExitBlock = blockContainer.Blocks[1];
setResultAndExitBlock = blockContainer.Blocks.ElementAtOrDefault(1);
if (setResultAndExitBlock == null) {
// This block can be absent if the function never exits normally,
// but always throws an exception/loops infinitely.
resultVar = null;
finalStateKnown = false; // final state will be detected in ValidateCatchBlock() instead
return;
}
// stobj System.Int32(ldflda [Field ICSharpCode.Decompiler.Tests.TestCases.Pretty.Async+<SimpleBoolTaskMethod>d__7.<>1__state](ldloc this), ldc.i4 -2)
// call SetResult(ldflda [Field ICSharpCode.Decompiler.Tests.TestCases.Pretty.Async+<SimpleBoolTaskMethod>d__7.<>t__builder](ldloc this), ldloc result)
// leave IL_0000
@ -397,6 +405,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -397,6 +405,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
throw new SymbolicAnalysisFailedException();
if (!MatchStateAssignment(setResultAndExitBlock.Instructions[0], out finalState))
throw new SymbolicAnalysisFailedException();
finalStateKnown = true;
if (!MatchCall(setResultAndExitBlock.Instructions[1], "SetResult", out var args))
throw new SymbolicAnalysisFailedException();
if (!IsBuilderFieldOnThis(args[0]))
@ -442,8 +451,15 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -442,8 +451,15 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (!stloc.Value.MatchLdLoc(handler.Variable))
throw new SymbolicAnalysisFailedException();
// stfld <>1__state(ldloc this, ldc.i4 -2)
if (!MatchStateAssignment(catchBlock.Instructions[1], out int newState) || newState != finalState)
if (!MatchStateAssignment(catchBlock.Instructions[1], out int newState))
throw new SymbolicAnalysisFailedException();
if (finalStateKnown) {
if (newState != finalState)
throw new SymbolicAnalysisFailedException();
} else {
finalState = newState;
finalStateKnown = true;
}
// call SetException(ldfld <>t__builder(ldloc this), ldloc exception)
if (!MatchCall(catchBlock.Instructions[2], "SetException", out var args))
throw new SymbolicAnalysisFailedException();

32
ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@ -31,7 +32,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -31,7 +32,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// then we can replace the variable with the argument.
/// 2) assignments of address-loading instructions to local variables
/// </summary>
public class CopyPropagation : IBlockTransform, IILTransform
public class CopyPropagation : IILTransform
{
public static void Propagate(StLoc store, ILTransformContext context)
{
@ -41,26 +42,25 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -41,26 +42,25 @@ namespace ICSharpCode.Decompiler.IL.Transforms
DoPropagate(store.Variable, store.Value, block, ref i, context);
}
public void Run(Block block, BlockTransformContext context)
{
RunOnBlock(block, context);
}
public void Run(ILFunction function, ILTransformContext context)
{
var splitVariables = new HashSet<ILVariable>(ILVariableEqualityComparer.Instance);
foreach (var g in function.Variables.GroupBy(v => v, ILVariableEqualityComparer.Instance)) {
if (g.Count() > 1) {
splitVariables.Add(g.Key);
}
}
foreach (var block in function.Descendants.OfType<Block>()) {
if (block.Kind != BlockKind.ControlFlow)
continue;
RunOnBlock(block, context);
RunOnBlock(block, context, splitVariables);
}
}
static void RunOnBlock(Block block, ILTransformContext context)
static void RunOnBlock(Block block, ILTransformContext context, HashSet<ILVariable> splitVariables = null)
{
for (int i = 0; i < block.Instructions.Count; i++) {
ILVariable v;
ILInstruction copiedExpr;
if (block.Instructions[i].MatchStLoc(out v, out copiedExpr)) {
if (block.Instructions[i].MatchStLoc(out ILVariable v, out ILInstruction copiedExpr)) {
if (v.IsSingleDefinition && v.LoadCount == 0 && v.Kind == VariableKind.StackSlot) {
// dead store to stack
if (SemanticHelper.IsPure(copiedExpr.Flags)) {
@ -76,18 +76,21 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -76,18 +76,21 @@ namespace ICSharpCode.Decompiler.IL.Transforms
copiedExpr.AddILRange(block.Instructions[i]);
block.Instructions[i] = copiedExpr;
}
} else if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr)) {
} else if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr, splitVariables)) {
DoPropagate(v, copiedExpr, block, ref i, context);
}
}
}
}
static bool CanPerformCopyPropagation(ILVariable target, ILInstruction value)
static bool CanPerformCopyPropagation(ILVariable target, ILInstruction value, HashSet<ILVariable> splitVariables)
{
Debug.Assert(target.StackType == value.ResultType);
if (target.Type.IsSmallIntegerType())
return false;
if (splitVariables != null && splitVariables.Contains(target)) {
return false; // non-local code move might change semantics when there's split variables
}
switch (value.OpCode) {
case OpCode.LdLoca:
// case OpCode.LdElema:
@ -100,6 +103,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -100,6 +103,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true;
case OpCode.LdLoc:
var v = ((LdLoc)value).Variable;
if (splitVariables != null && splitVariables.Contains(v)) {
return false; // non-local code move might change semantics when there's split variables
}
switch (v.Kind) {
case VariableKind.Parameter:
// Parameters can be copied only if they aren't assigned to (directly or indirectly via ldarga)

10
ILSpy/MainWindow.xaml.cs

@ -331,6 +331,10 @@ namespace ICSharpCode.ILSpy @@ -331,6 +331,10 @@ namespace ICSharpCode.ILSpy
}
}
}
} else if (navigateTo == "none") {
// Don't navigate anywhere; start empty.
// Used by ILSpy VS addin, it'll send us the real location to navigate to via IPC.
found = true;
} else {
IEntity mr = await Task.Run(() => FindEntityInRelevantAssemblies(navigateTo, relevantAssemblies));
if (mr != null && mr.ParentModule.PEFile != null) {
@ -354,15 +358,15 @@ namespace ICSharpCode.ILSpy @@ -354,15 +358,15 @@ namespace ICSharpCode.ILSpy
}
} else if (spySettings != null) {
SharpTreeNode node = null;
if (sessionSettings.ActiveTreeViewPath?.Length > 0) {
if (activeTreeViewPath?.Length > 0) {
foreach (var asm in assemblyList.GetAssemblies()) {
if (asm.FileName == sessionSettings.ActiveTreeViewPath[0]) {
if (asm.FileName == activeTreeViewPath[0]) {
// FindNodeByPath() blocks the UI if the assembly is not yet loaded,
// so use an async wait instead.
await asm.GetPEFileAsync().Catch<Exception>(ex => { });
}
}
node = FindNodeByPath(sessionSettings.ActiveTreeViewPath, true);
node = FindNodeByPath(activeTreeViewPath, true);
}
if (treeView.SelectedItem == initialSelection) {
if (node != null) {

2
ILSpy/Properties/AssemblyInfo.template.cs

@ -37,7 +37,7 @@ internal static class RevisionClass @@ -37,7 +37,7 @@ internal static class RevisionClass
{
public const string Major = "6";
public const string Minor = "0";
public const string Build = "0";
public const string Build = "1";
public const string Revision = "$INSERTREVISION$";
public const string VersionName = "alpha1";

1
appveyor.yml

@ -42,6 +42,7 @@ for: @@ -42,6 +42,7 @@ for:
- branches:
only:
- master
- 5.0.x
artifacts:
- path: ILSpy_binaries.zip
name: ILSpy %APPVEYOR_REPO_BRANCH% %ILSPY_VERSION_NUMBER% binaries

5
azure-pipelines.yml

@ -1,11 +1,10 @@ @@ -1,11 +1,10 @@
trigger:
- master
- msix
- 3.2.x
- 5.0.x
pr:
- master
- 3.2.x
- 5.0.x
variables:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true

Loading…
Cancel
Save