Browse Source

Fix potential NRE in ILFunction.RegisterVariable()

issue1638
Daniel Grunwald 4 years ago
parent
commit
0414e7f8e9
  1. 13
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  2. 5
      ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs
  3. 3
      ICSharpCode.Decompiler/IL/Transforms/FixLoneIsInst.cs
  4. 3
      ICSharpCode.Decompiler/IL/Transforms/FixRemainingIncrements.cs
  5. 17
      ICSharpCode.Decompiler/IL/Transforms/ILExtraction.cs
  6. 8
      ICSharpCode.Decompiler/IL/Transforms/NamedArgumentTransform.cs
  7. 2
      ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs

13
ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs

@ -412,18 +412,7 @@ namespace ICSharpCode.Decompiler.IL @@ -412,18 +412,7 @@ namespace ICSharpCode.Decompiler.IL
public ILVariable RegisterVariable(VariableKind kind, IType type, string? name = null)
{
return RegisterVariable(kind, type, type.GetStackType(), name);
}
public ILVariable RegisterVariable(VariableKind kind, StackType stackType, string? name = null)
{
var type = Method.Compilation.FindType(stackType.ToKnownTypeCode());
return RegisterVariable(kind, type, stackType, name);
}
ILVariable RegisterVariable(VariableKind kind, IType type, StackType stackType, string? name = null)
{
var variable = new ILVariable(kind, type, stackType);
var variable = new ILVariable(kind, type);
if (string.IsNullOrWhiteSpace(name))
{
name = "I_" + (helperVariableCount++);

5
ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs

@ -24,6 +24,7 @@ using System.Diagnostics; @@ -24,6 +24,7 @@ using System.Diagnostics;
using System.Threading;
using ICSharpCode.Decompiler.IL.Patterns;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
@ -899,9 +900,9 @@ namespace ICSharpCode.Decompiler.IL @@ -899,9 +900,9 @@ namespace ICSharpCode.Decompiler.IL
/// If extraction is not possible, the ILAst is left unmodified and the function returns null.
/// May return null if extraction is not possible.
/// </summary>
public ILVariable Extract()
public ILVariable Extract(ILTransformContext context)
{
return Transforms.ExtractionContext.Extract(this);
return Transforms.ExtractionContext.Extract(this, context);
}
/// <summary>

3
ICSharpCode.Decompiler/IL/Transforms/FixLoneIsInst.cs

@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
@ -63,7 +62,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -63,7 +62,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
// Use extraction to turn isInst.Argument into a pure instruction, thus making the emulation possible
context.Step("FixLoneIsInst", isInst);
isInst.Argument.Extract();
isInst.Argument.Extract(context);
}
}
}

3
ICSharpCode.Decompiler/IL/Transforms/FixRemainingIncrements.cs

@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@ -73,7 +72,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -73,7 +72,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
else
{
context.Step($"Fix {call.Method.Name} call at 0x{call.StartILOffset:x4} using new local", call);
var newVariable = call.Arguments[0].Extract();
var newVariable = call.Arguments[0].Extract(context);
if (newVariable == null)
{
Debug.Fail("Failed to extract argument of remaining increment/decrement");

17
ICSharpCode.Decompiler/IL/Transforms/ILExtraction.cs

@ -21,6 +21,8 @@ using System.Collections.Generic; @@ -21,6 +21,8 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.IL.Transforms
{
/// <summary>
@ -33,6 +35,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -33,6 +35,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// </summary>
readonly ILFunction Function;
readonly ILTransformContext context;
/// <summary>
/// Combined flags of all instructions being moved.
/// </summary>
@ -47,17 +51,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -47,17 +51,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// </summary>
readonly List<Func<ILInstruction>> MoveActions = new List<Func<ILInstruction>>();
ExtractionContext(ILFunction function)
ExtractionContext(ILFunction function, ILTransformContext context)
{
Debug.Assert(function != null);
this.Function = function;
this.context = context;
}
internal void RegisterMove(ILInstruction predecessor)
{
FlagsBeingMoved |= predecessor.Flags;
MoveActions.Add(delegate {
var v = Function.RegisterVariable(VariableKind.StackSlot, predecessor.ResultType);
var type = context.TypeSystem.FindType(predecessor.ResultType.ToKnownTypeCode());
var v = Function.RegisterVariable(VariableKind.StackSlot, type);
predecessor.ReplaceWith(new LdLoc(v));
return new StLoc(v, predecessor);
});
@ -91,10 +97,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -91,10 +97,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
///
/// May return null if extraction is not possible.
/// </summary>
public static ILVariable Extract(ILInstruction instToExtract)
public static ILVariable Extract(ILInstruction instToExtract, ILTransformContext context)
{
var function = instToExtract.Ancestors.OfType<ILFunction>().First();
ExtractionContext ctx = new ExtractionContext(function);
ExtractionContext ctx = new ExtractionContext(function, context);
ctx.FlagsBeingMoved = instToExtract.Flags;
ILInstruction inst = instToExtract;
while (inst != null)
@ -113,8 +119,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -113,8 +119,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
// We've reached the target block, and extraction is possible all the way.
int insertIndex = inst.ChildIndex;
var type = context.TypeSystem.FindType(instToExtract.ResultType.ToKnownTypeCode());
// Move instToExtract itself:
var v = function.RegisterVariable(VariableKind.StackSlot, instToExtract.ResultType);
var v = function.RegisterVariable(VariableKind.StackSlot, type);
instToExtract.ReplaceWith(new LdLoc(v));
block.Instructions.Insert(insertIndex, new StLoc(v, instToExtract));
// Apply the other move actions:

8
ICSharpCode.Decompiler/IL/Transforms/NamedArgumentTransform.cs

@ -1,8 +1,5 @@ @@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics;
using System.Linq;
using System.Text;
using ICSharpCode.Decompiler.TypeSystem;
@ -90,7 +87,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -90,7 +87,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
var call = (CallInstruction)arg.Parent;
Debug.Assert(context.Function == call.Ancestors.OfType<ILFunction>().First());
var v = context.Function.RegisterVariable(VariableKind.NamedArgument, arg.ResultType);
var type = context.TypeSystem.FindType(arg.ResultType.ToKnownTypeCode());
var v = context.Function.RegisterVariable(VariableKind.NamedArgument, type);
context.Step($"Introduce named argument '{v.Name}'", arg);
if (!(call.Parent is Block namedArgBlock) || namedArgBlock.Kind != BlockKind.CallWithNamedArgs)
{

2
ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs

@ -257,7 +257,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -257,7 +257,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var otherLoadOfV = v.LoadInstructions.FirstOrDefault(l => !(l.Parent is Cpblk));
if (otherLoadOfV == null)
return false;
finalStore = otherLoadOfV.Parent.Extract();
finalStore = otherLoadOfV.Parent.Extract(context);
if (finalStore == null)
return false;
value = ((StLoc)finalStore.StoreInstructions[0]).Value;

Loading…
Cancel
Save