Browse Source

#2092: ILFunction.Parameters / ILFunction.ReturnType should never be null.

pull/2113/head
Daniel Grunwald 5 years ago
parent
commit
b6b5f1e8e6
  1. 12
      ICSharpCode.Decompiler.Tests/DataFlowTest.cs
  2. 17
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  3. 4
      ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs

12
ICSharpCode.Decompiler.Tests/DataFlowTest.cs

@ -55,10 +55,14 @@ namespace ICSharpCode.Decompiler.Tests @@ -55,10 +55,14 @@ namespace ICSharpCode.Decompiler.Tests
public void TryFinallyWithAssignmentInFinally()
{
ILVariable v = new ILVariable(VariableKind.Local, SpecialType.UnknownType, 0);
ILFunction f = new ILFunction((IMethod)null, 0, new GenericContext(), new TryFinally(
new Nop(),
new StLoc(v, new LdcI4(0))
));
ILFunction f = new ILFunction(
returnType: SpecialType.UnknownType,
parameters: new IParameter[0],
genericContext: new GenericContext(),
body: new TryFinally(
new Nop(),
new StLoc(v, new LdcI4(0))
));
f.AddRef();
f.Variables.Add(v);
f.Body.AcceptVisitor(new RDTest(f, v));

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

@ -166,13 +166,11 @@ namespace ICSharpCode.Decompiler.IL @@ -166,13 +166,11 @@ namespace ICSharpCode.Decompiler.IL
/// <summary>
/// Return type of this function.
/// Might be null, if this function was not created from metadata.
/// </summary>
public readonly IType ReturnType;
/// <summary>
/// List of parameters of this function.
/// Might be null, if this function was not created from metadata.
/// </summary>
public readonly IReadOnlyList<IParameter> Parameters;
@ -188,17 +186,16 @@ namespace ICSharpCode.Decompiler.IL @@ -188,17 +186,16 @@ namespace ICSharpCode.Decompiler.IL
/// </summary>
/// <remarks>
/// Use <see cref="ILReader"/> to create ILAst.
/// <paramref name="method"/> may be null.
/// </remarks>
public ILFunction(IMethod method, int codeSize, GenericContext genericContext, ILInstruction body, ILFunctionKind kind = ILFunctionKind.TopLevelFunction) : base(OpCode.ILFunction)
{
this.Method = method;
this.Name = Method?.Name;
this.Name = method.Name;
this.CodeSize = codeSize;
this.GenericContext = genericContext;
this.Body = body;
this.ReturnType = Method?.ReturnType;
this.Parameters = Method?.Parameters;
this.ReturnType = method.ReturnType;
this.Parameters = method.Parameters;
this.Variables = new ILVariableCollection(this);
this.LocalFunctions = new InstructionCollection<ILFunction>(this, 1);
this.kind = kind;
@ -207,15 +204,15 @@ namespace ICSharpCode.Decompiler.IL @@ -207,15 +204,15 @@ namespace ICSharpCode.Decompiler.IL
/// <summary>
/// This constructor is only to be used by the TransformExpressionTrees step.
/// </summary>
internal ILFunction(IType returnType, IReadOnlyList<IParameter> parameters, GenericContext genericContext, ILInstruction body) : base(OpCode.ILFunction)
internal ILFunction(IType returnType, IReadOnlyList<IParameter> parameters, GenericContext genericContext, ILInstruction body, ILFunctionKind kind = ILFunctionKind.TopLevelFunction) : base(OpCode.ILFunction)
{
this.GenericContext = genericContext;
this.Body = body;
this.ReturnType = returnType;
this.Parameters = parameters;
this.ReturnType = returnType ?? throw new ArgumentNullException(nameof(returnType));
this.Parameters = parameters ?? throw new ArgumentNullException(nameof(parameters));
this.Variables = new ILVariableCollection(this);
this.LocalFunctions = new InstructionCollection<ILFunction>(this, 1);
this.kind = ILFunctionKind.ExpressionTree;
this.kind = kind;
}
internal override void CheckInvariant(ILPhase phase)

4
ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs

@ -156,8 +156,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -156,8 +156,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var container = new BlockContainer();
container.AddILRange(instruction);
var functionType = instruction.Method.ReturnType.TypeArguments[0];
var returnType = functionType.GetDelegateInvokeMethod()?.ReturnType;
var function = new ILFunction(returnType, parameterList, context.Function.GenericContext, container);
var returnType = functionType.GetDelegateInvokeMethod()?.ReturnType ?? SpecialType.UnknownType;
var function = new ILFunction(returnType, parameterList, context.Function.GenericContext, container, ILFunctionKind.ExpressionTree);
function.DelegateType = functionType;
function.Kind = IsExpressionTree(functionType) ? ILFunctionKind.ExpressionTree : ILFunctionKind.Delegate;
function.Variables.AddRange(parameterVariablesList);

Loading…
Cancel
Save