Skip to content

Commit

Permalink
Canonicalize arguments before loading instantiation when dropGenericA…
Browse files Browse the repository at this point in the history
…rgumentLevel is TRUE
  • Loading branch information
Fadi Hanna committed Apr 9, 2020
1 parent 7b90ab2 commit a04b965
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/coreclr/src/vm/siginfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1356,7 +1356,7 @@ TypeHandle SigPointer::GetTypeHandleThrowing(
if (tmpEType == ELEMENT_TYPE_CLASS)
typeHnd = TypeHandle(g_pCanonMethodTableClass);
}
else if ((elemType == (CorElementType) ELEMENT_TYPE_CANON_ZAPSIG) ||
else if ((elemType == (CorElementType)ELEMENT_TYPE_CANON_ZAPSIG) ||
(CorTypeInfo::GetGCType_NoThrow(elemType) == TYPE_GC_REF))
{
typeHnd = TypeHandle(g_pCanonMethodTableClass);
Expand Down Expand Up @@ -1389,6 +1389,11 @@ TypeHandle SigPointer::GetTypeHandleThrowing(
thisinst = NULL;
break;
}

if (dropGenericArgumentLevel && level == CLASS_LOAD_APPROXPARENTS)
{
typeHnd = ClassLoader::CanonicalizeGenericArg(typeHnd);
}
}
thisinst[i] = typeHnd;
IfFailThrowBF(psig.SkipExactlyOne(), BFA_BAD_SIGNATURE, pOrigModule);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

public struct MyStruct<TRequest, TResponse>
{
int _id;
public MyStruct(int id) { _id = id; }
public override string ToString() => this.GetType().ToString() + " = " + _id;
}

public struct GenStruct<T> { }

public sealed class MyStructWrapper<TRequest, TResponse>
{
public MyStruct<TRequest, TResponse> _field;

public MyStructWrapper(MyStruct<TRequest, TResponse> value)
{
_field = value;
}

[MethodImpl(MethodImplOptions.NoInlining)]
public override string ToString() => _field.ToString();
}

public abstract class BaseStructCreator
{
public abstract MyStructWrapper<TRequest, TResponse> GetMyStructWrapper<TRequest, TResponse>() where TRequest : class;
}

public class StructCreator : BaseStructCreator
{
public override MyStructWrapper<TRequest, TResponse> GetMyStructWrapper<TRequest, TResponse>()
{
return new MyStructWrapper<TRequest, TResponse>(CreateCall<TRequest, TResponse>());
}
protected virtual MyStruct<TRequest, TResponse> CreateCall<TRequest, TResponse>() where TRequest : class
{
return new MyStruct<TRequest, TResponse>(123);
}
}

class DerivedCreator : StructCreator
{
protected override MyStruct<TRequest, TResponse> CreateCall<TRequest, TResponse>()
{
return new MyStruct<TRequest, TResponse>(456);
}
}

public class Test
{
[MethodImpl(MethodImplOptions.NoInlining)]
static string RunTest()
{
var creator = new DerivedCreator();
var wrapper = creator.GetMyStructWrapper<Exception, GenStruct<string>>();
return wrapper.ToString();
}
public static int Main()
{
Console.WriteLine("Expected: MyStruct`2[System.Exception,GenStruct`1[System.String]] = 456");

string result = RunTest();
Console.WriteLine("Actual : " + result);

string expected = "MyStruct`2[System.Exception,GenStruct`1[System.String]] = 456";
return result == expected ? 100 : -1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<CLRTestKind>BuildAndRun</CLRTestKind>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>

<PropertyGroup>
<CLRTestBatchPreCommands><![CDATA[
$(CLRTestBatchPreCommands)
set COMPlus_gcServer=1
set COMPlus_gcStress=7
]]></CLRTestBatchPreCommands>
<BashCLRTestPreCommands><![CDATA[
$(BashCLRTestPreCommands)
export COMPlus_gcServer=1
export COMPlus_gcStress=7
]]></BashCLRTestPreCommands>
</PropertyGroup>

</Project>

0 comments on commit a04b965

Please sign in to comment.