diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index 36b7ffa386..69300d285b 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -936,6 +936,12 @@ public async Task Issue3684([ValueSource(nameof(roslyn4OrNewerOptions))] Compile await RunForLibrary(cscOptions: cscOptions); } + [Test] + public async Task Issue3751([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) + { + await RunForLibrary(cscOptions: cscOptions); + } + async Task RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, Action configureDecompiler = null) { await Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, configureDecompiler); diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3751.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3751.cs new file mode 100644 index 0000000000..536f859fec --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3751.cs @@ -0,0 +1,28 @@ +using System; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty +{ + internal class Issue3751 + { + private static bool Cond; + + private static T Infer(Func factory) + { + return factory(); + } + + public object Trigger() + { + return Infer(delegate { + if (Cond) + { + Console.WriteLine(); + return null; + } + return new { + Value = 1 + }; + }); + } + } +} diff --git a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs index 3c7ff756b8..66c9666028 100644 --- a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs @@ -382,6 +382,21 @@ protected internal override TranslatedStatement VisitLeave(Leave inst) .WithRR(new ConversionResolveResult(currentResultType, expr.ResolveResult, Conversion.IdentityConversion)).WithoutILInstruction(); } return new ReturnStatement(expr).WithILInstruction(inst); + + static bool IsPossibleLossOfTypeInformation(IType givenType, IType expectedType) + { + if (expectedType.ContainsAnonymousType()) + return false; + if (NormalizeTypeVisitor.IgnoreNullability.EquivalentTypes(givenType, expectedType)) + return false; + if (expectedType is TupleType { ElementNames.IsEmpty: false }) + return true; + if (expectedType == SpecialType.Dynamic) + return true; + if (givenType == SpecialType.NullType) + return true; + return false; + } } else return new ReturnStatement().WithILInstruction(inst); @@ -403,19 +418,6 @@ protected internal override TranslatedStatement VisitLeave(Leave inst) return new GotoStatement(label).WithILInstruction(inst); } - private bool IsPossibleLossOfTypeInformation(IType givenType, IType expectedType) - { - if (NormalizeTypeVisitor.IgnoreNullability.EquivalentTypes(givenType, expectedType)) - return false; - if (expectedType is TupleType { ElementNames.IsEmpty: false }) - return true; - if (expectedType == SpecialType.Dynamic) - return true; - if (givenType == SpecialType.NullType) - return true; - return false; - } - protected internal override TranslatedStatement VisitThrow(Throw inst) { return new ThrowStatement(exprBuilder.Translate(inst.Argument)).WithILInstruction(inst);