Browse Source

Fix #882: Don't inline value-type temporaries for setter calls.

pull/1464/head
Daniel Grunwald 7 years ago
parent
commit
4ad4f6a232
  1. 8
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs
  2. 8
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

8
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs

@ -480,8 +480,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public void ForEachOverListOfStruct(List<DataItem> items, int value) public void ForEachOverListOfStruct(List<DataItem> items, int value)
{ {
foreach (DataItem item in items) { foreach (DataItem item in items) {
#if ROSLYN && OPT
// The variable name differs based on whether roslyn optimizes out the 'item' variable
DataItem current = item;
current.Property = value;
#else
DataItem dataItem = item; DataItem dataItem = item;
dataItem.Property = value; dataItem.Property = value;
#endif
} }
} }
@ -671,7 +677,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
} }
//other configurations work fine, just with different labels //other configurations work fine, just with different labels
#if OPT && !MCS #if OPT && !MCS
public void WhileWithGoto() public void WhileWithGoto()
{ {
while (Condition("Main Loop")) { while (Condition("Main Loop")) {

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

@ -19,6 +19,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.IL.Transforms namespace ICSharpCode.Decompiler.IL.Transforms
@ -275,7 +276,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
switch (ldloca.Parent.OpCode) { switch (ldloca.Parent.OpCode) {
case OpCode.Call: case OpCode.Call:
case OpCode.CallVirt: case OpCode.CallVirt:
return !((CallInstruction)ldloca.Parent).Method.IsStatic; var method = ((CallInstruction)ldloca.Parent).Method;
if (method.IsAccessor && method.AccessorKind != MethodSemanticsAttributes.Getter) {
// C# doesn't allow calling setters on temporary structs
return false;
}
return !method.IsStatic;
case OpCode.Await: case OpCode.Await:
return true; return true;
default: default:

Loading…
Cancel
Save