diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
index b6d2af5ad..cafcf2dad 100644
--- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
+++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
@@ -163,6 +163,7 @@
+
diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
index ffedb0b0e..ce1793293 100644
--- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
+++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
@@ -718,6 +718,12 @@ namespace ICSharpCode.Decompiler.Tests
await RunForLibrary(cscOptions: cscOptions);
}
+ [Test]
+ public async Task Issue3584([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
+ {
+ await RunForLibrary(cscOptions: cscOptions);
+ }
+
[Test]
public async Task AssemblyCustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3584.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3584.cs
new file mode 100644
index 000000000..3c583d827
--- /dev/null
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3584.cs
@@ -0,0 +1,47 @@
+using System.Collections;
+using System.Collections.Generic;
+
+namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
+{
+ internal abstract class Issue4000 : IEnumerable, IEnumerable
+ {
+ public int Length;
+
+ protected T[] results;
+
+#if !ROSLYN4
+ public T this[int i] {
+ get {
+ if (i >= Length || i < 0)
+ {
+ return default(T);
+ }
+ if (results[i] != null && results[i].Equals(default(T)))
+ {
+ results[i] = CreateIthElement(i);
+ }
+ return results[i];
+ }
+ }
+#endif
+
+ protected abstract T CreateIthElement(int i);
+
+ public IEnumerator GetEnumerator()
+ {
+ for (int i = 0; i < Length; i++)
+ {
+ if (results[i] != null && results[i].Equals(default(T)))
+ {
+ results[i] = CreateIthElement(i);
+ }
+ yield return results[i];
+ }
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+}
diff --git a/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs b/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs
index fda8cb533..4977eba37 100644
--- a/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs
+++ b/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs
@@ -238,6 +238,8 @@ namespace ICSharpCode.Decompiler.IL
default:
return SpecialType.UnknownType;
}
+ case DefaultValue defaultValue:
+ return defaultValue.Type;
case ILFunction func when func.DelegateType != null:
return func.DelegateType;
default:
diff --git a/ICSharpCode.Decompiler/IL/Instructions.cs b/ICSharpCode.Decompiler/IL/Instructions.cs
index b3a73d336..96a6bd948 100644
--- a/ICSharpCode.Decompiler/IL/Instructions.cs
+++ b/ICSharpCode.Decompiler/IL/Instructions.cs
@@ -318,6 +318,7 @@ namespace ICSharpCode.Decompiler.IL
set {
ValidateChild(value);
SetChildInstruction(ref this.argument, value, 0);
+ InvalidateFlags();
}
}
protected sealed override int GetChildCount()
@@ -4357,10 +4358,19 @@ namespace ICSharpCode.Decompiler.IL
public override StackType ResultType { get { return StackType.O; } }
protected override InstructionFlags ComputeFlags()
{
- return base.ComputeFlags() | InstructionFlags.SideEffect | InstructionFlags.MayThrow;
+ var baseFlags = base.ComputeFlags();
+ if (baseFlags == InstructionFlags.None && Type.Equals(Argument.InferType(null)))
+ {
+ return InstructionFlags.None;
+ }
+ return baseFlags | InstructionFlags.SideEffect | InstructionFlags.MayThrow;
}
public override InstructionFlags DirectFlags {
get {
+ if (Flags == InstructionFlags.None)
+ {
+ return InstructionFlags.None;
+ }
return base.DirectFlags | InstructionFlags.SideEffect | InstructionFlags.MayThrow;
}
}