From 6c193ac50eb4036088079eb83592957a372ec438 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 24 Nov 2018 15:16:51 +0100 Subject: [PATCH] Fix #1323: NRE in DetectBestEnumValueDisplayMode; emit error message, if enum field definition has no constant value. --- .../ICSharpCode.Decompiler.Tests.csproj | 2 ++ .../ILPrettyTestRunner.cs | 6 +++++ .../CSharp/CSharpDecompiler.cs | 22 +++++++++++-------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index df2247f18..f098becf4 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -71,12 +71,14 @@ + + diff --git a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs index 12fcbb8fd..226f1c151 100644 --- a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs @@ -124,6 +124,12 @@ namespace ICSharpCode.Decompiler.Tests Run(); } + [Test] + public void Issue1323() + { + Run(); + } + [Test] public void FSharpLoops_Debug() { diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index 73a948968..01f8a8abb 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -984,6 +984,9 @@ namespace ICSharpCode.Decompiler.CSharp case EnumValueDisplayMode.None: foreach (var enumMember in typeDecl.Members.OfType()) { enumMember.Initializer = null; + if (enumMember.GetSymbol() is IField f && f.ConstantValue == null) { + typeDecl.InsertChildBefore(enumMember, new Comment(" error: enumerator has no value"), Roles.Comment); + } } break; case EnumValueDisplayMode.All: @@ -1010,7 +1013,7 @@ namespace ICSharpCode.Decompiler.CSharp bool first = true; long firstValue = 0, previousValue = 0; foreach (var field in typeDef.Fields) { - if (MemberIsHidden(module, field.MetadataToken, settings)) continue; + if (MemberIsHidden(module, field.MetadataToken, settings) || field.ConstantValue == null) continue; long currentValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false); if (first) { firstValue = currentValue; @@ -1237,15 +1240,16 @@ namespace ICSharpCode.Decompiler.CSharp { Debug.Assert(decompilationContext.CurrentMember == field); var typeSystemAstBuilder = CreateAstBuilder(decompilationContext); - if (decompilationContext.CurrentTypeDefinition.Kind == TypeKind.Enum && field.ConstantValue != null) { + if (decompilationContext.CurrentTypeDefinition.Kind == TypeKind.Enum) { var enumDec = new EnumMemberDeclaration { Name = field.Name }; - long initValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false); - enumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, field.ConstantValue); - if (enumDec.Initializer is PrimitiveExpression primitive - && initValue >= 0 && (decompilationContext.CurrentTypeDefinition.HasAttribute(KnownAttribute.Flags) - || (initValue > 9 && (unchecked(initValue & (initValue - 1)) == 0 || unchecked(initValue & (initValue + 1)) == 0)))) - { - primitive.SetValue(initValue, $"0x{initValue:X}"); + if (field.ConstantValue != null) { + long initValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false); + enumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, field.ConstantValue); + if (enumDec.Initializer is PrimitiveExpression primitive + && initValue >= 0 && (decompilationContext.CurrentTypeDefinition.HasAttribute(KnownAttribute.Flags) + || (initValue > 9 && (unchecked(initValue & (initValue - 1)) == 0 || unchecked(initValue & (initValue + 1)) == 0)))) { + primitive.SetValue(initValue, $"0x{initValue:X}"); + } } enumDec.Attributes.AddRange(field.GetAttributes().Select(a => new AttributeSection(typeSystemAstBuilder.ConvertAttribute(a)))); enumDec.AddAnnotation(new MemberResolveResult(null, field));