Browse Source

Fix #2115: Re-introduce the evaluation order bug #2050 when a language version <=C# 5 is selected.

pull/2145/head
Daniel Grunwald 5 years ago
parent
commit
bb99e9668a
  1. 6
      ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
  2. 8
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  3. 24
      ICSharpCode.Decompiler/DecompilerSettings.cs
  4. 20
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs
  5. 27
      ILSpy/Properties/Resources.Designer.cs
  6. 9
      ILSpy/Properties/Resources.resx
  7. 6
      ILSpy/Properties/Resources.zh-Hans.resx

6
ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs

@ -142,7 +142,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -142,7 +142,7 @@ namespace ICSharpCode.Decompiler.Tests
[Test]
public void NullableTests([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options, forceRoslynRecompile: true);
RunCS(options: options);
}
[Test]
@ -315,7 +315,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -315,7 +315,7 @@ namespace ICSharpCode.Decompiler.Tests
RunCS(options: options);
}
void RunCS([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug, bool forceRoslynRecompile = false)
void RunCS([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug)
{
string testFileName = testName + ".cs";
string testOutputFileName = testName + Tester.GetSuffix(options) + ".exe";
@ -326,7 +326,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -326,7 +326,7 @@ namespace ICSharpCode.Decompiler.Tests
outputFile = Tester.CompileCSharp(Path.Combine(TestCasePath, testFileName), options,
outputFileName: Path.Combine(TestCasePath, testOutputFileName));
string decompiledCodeFile = Tester.DecompileCSharp(outputFile.PathToAssembly, Tester.GetSettings(options));
if (forceRoslynRecompile || options.HasFlag(CompilerOptions.UseMcs))
if (options.HasFlag(CompilerOptions.UseMcs))
{
// For second pass, use roslyn instead of mcs.
// mcs has some compiler bugs that cause it to not accept ILSpy-generated code,

8
ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

@ -464,7 +464,13 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -464,7 +464,13 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
}
else
{
return new DecompilerSettings(CSharp.LanguageVersion.CSharp5);
var settings= new DecompilerSettings(CSharp.LanguageVersion.CSharp5);
if (cscOptions.HasFlag(CompilerOptions.UseMcs))
{
// we don't recompile with mcs but with roslyn, so we can use ref locals
settings.UseRefLocalsForAccurateOrderOfEvaluation = true;
}
return settings;
}
}

24
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -92,6 +92,7 @@ namespace ICSharpCode.Decompiler @@ -92,6 +92,7 @@ namespace ICSharpCode.Decompiler
stringInterpolation = false;
dictionaryInitializers = false;
extensionMethodsInCollectionInitializers = false;
useRefLocalsForAccurateOrderOfEvaluation = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp7)
{
@ -153,7 +154,7 @@ namespace ICSharpCode.Decompiler @@ -153,7 +154,7 @@ namespace ICSharpCode.Decompiler
|| discards || localFunctions)
return CSharp.LanguageVersion.CSharp7;
if (awaitInCatchFinally || useExpressionBodyForCalculatedGetterOnlyProperties || nullPropagation
|| stringInterpolation || dictionaryInitializers || extensionMethodsInCollectionInitializers)
|| stringInterpolation || dictionaryInitializers || extensionMethodsInCollectionInitializers || useRefLocalsForAccurateOrderOfEvaluation)
return CSharp.LanguageVersion.CSharp6;
if (asyncAwait)
return CSharp.LanguageVersion.CSharp5;
@ -445,7 +446,7 @@ namespace ICSharpCode.Decompiler @@ -445,7 +446,7 @@ namespace ICSharpCode.Decompiler
/// Decompile C# 6 ?. and ?[] operators.
/// </summary>
[Category("C# 6.0 / VS 2015")]
[Description("DecompilerSettings.DecompileAndOperators")]
[Description("DecompilerSettings.NullPropagation")]
public bool NullPropagation {
get { return nullPropagation; }
set {
@ -819,6 +820,25 @@ namespace ICSharpCode.Decompiler @@ -819,6 +820,25 @@ namespace ICSharpCode.Decompiler
}
}
bool useRefLocalsForAccurateOrderOfEvaluation = true;
/// <summary>
/// Gets/Sets whether to use C# 6.0 Extension Add methods in collection initializers.
/// Only has an effect if ObjectOrCollectionInitializers is enabled.
/// </summary>
[Category("C# 6.0 / VS 2015")]
[Description("DecompilerSettings.UseRefLocalsForAccurateOrderOfEvaluation")]
public bool UseRefLocalsForAccurateOrderOfEvaluation {
get { return useRefLocalsForAccurateOrderOfEvaluation; }
set {
if (useRefLocalsForAccurateOrderOfEvaluation != value)
{
useRefLocalsForAccurateOrderOfEvaluation = value;
OnPropertyChanged();
}
}
}
bool refExtensionMethods = true;
/// <summary>

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

@ -33,6 +33,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -33,6 +33,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
Aggressive = 1,
IntroduceNamedArguments = 2,
FindDeconstruction = 4,
AllowChangingOrderOfEvaluationForExceptions = 8,
}
/// <summary>
@ -73,6 +74,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -73,6 +74,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (IsInConstructorInitializer(function, inst))
options |= InliningOptions.Aggressive;
}
if (!context.Settings.UseRefLocalsForAccurateOrderOfEvaluation)
{
options |= InliningOptions.AllowChangingOrderOfEvaluationForExceptions;
}
return options;
}
@ -667,8 +672,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -667,8 +672,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// Match found, we can inline
if (expr.SlotInfo == StObj.TargetSlot && !((StObj)expr.Parent).CanInlineIntoTargetSlot(expressionBeingMoved))
{
// special case: the StObj.TargetSlot does not accept some kinds of expressions
return FindResult.Stop;
if ((options & InliningOptions.AllowChangingOrderOfEvaluationForExceptions) != 0)
{
// Intentionally change code semantics so that we can avoid a ref local
if (expressionBeingMoved is LdFlda ldflda)
ldflda.DelayExceptions = true;
else if (expressionBeingMoved is LdElema ldelema)
ldelema.DelayExceptions = true;
}
else
{
// special case: the StObj.TargetSlot does not accept some kinds of expressions
return FindResult.Stop;
}
}
return FindResult.Found(expr);
}

27
ILSpy/Properties/Resources.Designer.cs generated

@ -711,15 +711,6 @@ namespace ICSharpCode.ILSpy.Properties { @@ -711,15 +711,6 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Decompile ?. and ?[] operators.
/// </summary>
public static string DecompilerSettings_DecompileAndOperators {
get {
return ResourceManager.GetString("DecompilerSettings.DecompileAndOperators", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Decompile anonymous methods/lambdas.
/// </summary>
@ -1010,6 +1001,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -1010,6 +1001,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Decompile ?. and ?[] operators.
/// </summary>
public static string DecompilerSettings_NullPropagation {
get {
return ResourceManager.GetString("DecompilerSettings.NullPropagation", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Object/collection initializer expressions.
/// </summary>
@ -1217,6 +1217,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -1217,6 +1217,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Use ref locals to accurately represent order of evaluation.
/// </summary>
public static string DecompilerSettings_UseRefLocalsForAccurateOrderOfEvaluation {
get {
return ResourceManager.GetString("DecompilerSettings.UseRefLocalsForAccurateOrderOfEvaluation", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use new SDK style format for generated project files (*.csproj).
/// </summary>

9
ILSpy/Properties/Resources.resx

@ -267,9 +267,6 @@ Are you sure you want to continue?</value> @@ -267,9 +267,6 @@ Are you sure you want to continue?</value>
<data name="DecompilerSettings.AsyncEnumerator" xml:space="preserve">
<value>Decompile async IAsyncEnumerator methods</value>
</data>
<data name="DecompilerSettings.DecompileAndOperators" xml:space="preserve">
<value>Decompile ?. and ?[] operators</value>
</data>
<data name="DecompilerSettings.DecompileAnonymousMethodsLambdas" xml:space="preserve">
<value>Decompile anonymous methods/lambdas</value>
</data>
@ -363,6 +360,9 @@ Are you sure you want to continue?</value> @@ -363,6 +360,9 @@ Are you sure you want to continue?</value>
<data name="DecompilerSettings.NativeIntegers" xml:space="preserve">
<value>Use nint/nuint types</value>
</data>
<data name="DecompilerSettings.NullPropagation" xml:space="preserve">
<value>Decompile ?. and ?[] operators</value>
</data>
<data name="DecompilerSettings.NullableReferenceTypes" xml:space="preserve">
<value>Nullable reference types</value>
</data>
@ -435,6 +435,9 @@ Are you sure you want to continue?</value> @@ -435,6 +435,9 @@ Are you sure you want to continue?</value>
<data name="DecompilerSettings.UsePatternBasedFixedStatement" xml:space="preserve">
<value>Use pattern-based fixed statement</value>
</data>
<data name="DecompilerSettings.UseRefLocalsForAccurateOrderOfEvaluation" xml:space="preserve">
<value>Use ref locals to accurately represent order of evaluation</value>
</data>
<data name="DecompilerSettings.UseSdkStyleProjectFormat" xml:space="preserve">
<value>Use new SDK style format for generated project files (*.csproj)</value>
</data>

6
ILSpy/Properties/Resources.zh-Hans.resx

@ -258,9 +258,6 @@ @@ -258,9 +258,6 @@
<data name="DecompilerSettings.AsyncEnumerator" xml:space="preserve">
<value>反编译异步 IAsyncEnumerator 方法</value>
</data>
<data name="DecompilerSettings.DecompileAndOperators" xml:space="preserve">
<value>反编译 ?. 和 ?[] 运算符</value>
</data>
<data name="DecompilerSettings.DecompileAnonymousMethodsLambdas" xml:space="preserve">
<value>反编译匿名方法或 lambda</value>
</data>
@ -348,6 +345,9 @@ @@ -348,6 +345,9 @@
<data name="DecompilerSettings.NativeIntegers" xml:space="preserve">
<value>使用 nint/nuint 类型</value>
</data>
<data name="DecompilerSettings.NullPropagation" xml:space="preserve">
<value>反编译 ?. 和 ?[] 运算符</value>
</data>
<data name="DecompilerSettings.NullableReferenceTypes" xml:space="preserve">
<value>可空引用类型</value>
</data>

Loading…
Cancel
Save