Browse Source

Fix casts to type parameters.

pull/728/merge
Daniel Grunwald 9 years ago
parent
commit
8d2116dea7
  1. 15
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 2
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs
  3. 13
      ICSharpCode.Decompiler/Tests/TestCases/Correctness/Generics.cs

15
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1307,9 +1307,20 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1307,9 +1307,20 @@ namespace ICSharpCode.Decompiler.CSharp
// ensure we treat the input as a reference type
arg = arg.ConvertTo(compilation.FindType(KnownTypeCode.Object), this);
}
return new CastExpression(ConvertType(inst.Type), arg.Expression)
IType targetType = inst.Type;
if (targetType.Kind == TypeKind.TypeParameter) {
var rr = resolver.ResolveCast(targetType, arg.ResolveResult);
if (rr.IsError) {
// C# 6.2.7 Explicit conversions involving type parameters:
// if we can't directly convert to a type parameter,
// try via its effective base class.
arg = arg.ConvertTo(((ITypeParameter)targetType).EffectiveBaseClass, this);
}
}
return new CastExpression(ConvertType(targetType), arg.Expression)
.WithILInstruction(inst)
.WithRR(new ConversionResolveResult(inst.Type, arg.ResolveResult, Conversion.UnboxingConversion));
.WithRR(new ConversionResolveResult(targetType, arg.ResolveResult, Conversion.UnboxingConversion));
}
protected internal override TranslatedExpression VisitUnbox(Unbox inst, TranslationContext context)

2
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -248,7 +248,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -248,7 +248,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} else {
ILInstruction value;
ILVariable v;
if (inst.Value.MatchLdLoc(out v)) {
if (inst.Value.MatchLdLoc(out v) && v.Kind != VariableKind.PinnedLocal) {
orphanedVariableInits.Add(inst);
value = inst.Value;
} else {

13
ICSharpCode.Decompiler/Tests/TestCases/Correctness/Generics.cs

@ -47,6 +47,11 @@ namespace Generics @@ -47,6 +47,11 @@ namespace Generics
{
Console.WriteLine(typeof(T1) + " " + typeof(T2));
}
public T CastToTypeParameter<T>(DerivedClass d) where T: BaseClass
{
return (T)(BaseClass)d;
}
}
class GenericClass<T>
@ -56,4 +61,12 @@ namespace Generics @@ -56,4 +61,12 @@ namespace Generics
self = this;
}
}
public class BaseClass
{
}
public class DerivedClass : BaseClass
{
}
}

Loading…
Cancel
Save