Browse Source

Fixed NullReferenceException when decompiling a switch over a boolean variable that includes a default case.

pull/314/merge
Daniel Grunwald 14 years ago
parent
commit
63a55fa5b0
  1. 34
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 8
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  3. 12
      ICSharpCode.Decompiler/Tests/Switch.cs

34
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.Ast
TypeDefinition type = member as TypeDefinition;
if (type != null) {
if (type.DeclaringType != null) {
if (type.DeclaringType != null) {
if (settings.AnonymousMethods && IsClosureType(type))
return true;
if (settings.YieldReturn && YieldReturnDecompiler.IsCompilerGeneratorEnumerator(type))
@ -91,12 +91,12 @@ namespace ICSharpCode.Decompiler.Ast @@ -91,12 +91,12 @@ namespace ICSharpCode.Decompiler.Ast
FieldDefinition field = member as FieldDefinition;
if (field != null) {
if (field.IsCompilerGenerated()) {
if (field.IsCompilerGenerated()) {
if (settings.AnonymousMethods && IsAnonymousMethodCacheField(field))
return true;
return true;
if (settings.AutomaticProperties && IsAutomaticPropertyBackingField(field))
return true;
if (settings.SwitchStatementOnString && IsSwitchOnStringCache(field))
return true;
if (settings.SwitchStatementOnString && IsSwitchOnStringCache(field))
return true;
}
// event-fields are not [CompilerGenerated]
@ -107,24 +107,24 @@ namespace ICSharpCode.Decompiler.Ast @@ -107,24 +107,24 @@ namespace ICSharpCode.Decompiler.Ast
return false;
}
static bool IsSwitchOnStringCache(FieldDefinition field)
{
return field.Name.StartsWith("<>f__switch", StringComparison.Ordinal);
static bool IsSwitchOnStringCache(FieldDefinition field)
{
return field.Name.StartsWith("<>f__switch", StringComparison.Ordinal);
}
static bool IsAutomaticPropertyBackingField(FieldDefinition field)
{
return field.HasGeneratedName() && field.Name.EndsWith("BackingField", StringComparison.Ordinal);
static bool IsAutomaticPropertyBackingField(FieldDefinition field)
{
return field.HasGeneratedName() && field.Name.EndsWith("BackingField", StringComparison.Ordinal);
}
static bool IsAnonymousMethodCacheField(FieldDefinition field)
{
return field.Name.StartsWith("CS$<>", StringComparison.Ordinal) || field.Name.StartsWith("<>f__am", StringComparison.Ordinal);
static bool IsAnonymousMethodCacheField(FieldDefinition field)
{
return field.Name.StartsWith("CS$<>", StringComparison.Ordinal) || field.Name.StartsWith("<>f__am", StringComparison.Ordinal);
}
static bool IsClosureType(TypeDefinition type)
{
return type.HasGeneratedName() && type.IsCompilerGenerated() && (type.Name.Contains("DisplayClass") || type.Name.Contains("AnonStorey"));
static bool IsClosureType(TypeDefinition type)
{
return type.HasGeneratedName() && type.IsCompilerGenerated() && (type.Name.Contains("DisplayClass") || type.Name.Contains("AnonStorey"));
}
/// <summary>

8
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -175,7 +175,13 @@ namespace ICSharpCode.Decompiler.Ast @@ -175,7 +175,13 @@ namespace ICSharpCode.Decompiler.Ast
};
} else if (node is ILSwitch) {
ILSwitch ilSwitch = (ILSwitch)node;
if (TypeAnalysis.IsBoolean(ilSwitch.Condition.InferredType) && ilSwitch.CaseBlocks.SelectMany(cb => cb.Values).Any(val => val != 0 && val != 1)) {
if (TypeAnalysis.IsBoolean(ilSwitch.Condition.InferredType) && (
from cb in ilSwitch.CaseBlocks
where cb.Values != null
from val in cb.Values
select val
).Any(val => val != 0 && val != 1))
{
// If switch cases contain values other then 0 and 1, force the condition to be non-boolean
ilSwitch.Condition.ExpectedType = typeSystem.Int32;
}

12
ICSharpCode.Decompiler/Tests/Switch.cs

@ -74,4 +74,16 @@ public static class Switch @@ -74,4 +74,16 @@ public static class Switch
return "Default";
}
}
public static string SwitchOverBool(bool b)
{
switch (b) {
case true:
return bool.TrueString;
case false:
return bool.FalseString;
default:
return null;
}
}
}

Loading…
Cancel
Save