Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Type.ContainsGenericParameters for function pointers #90864

Merged
merged 4 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/coreclr/vm/typedesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,31 @@ BOOL TypeDesc::IsSharedByGenericInstantiations()
return FALSE;
}

BOOL TypeDesc::ContainsGenericVariables(BOOL methodOnly)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation mirrors structure of IsSharedByGenericInstantiations

{
if (IsGenericVariable())
{
if (!methodOnly)
return TRUE;

PTR_TypeVarTypeDesc pTyVar = dac_cast<PTR_TypeVarTypeDesc>(this);
return TypeFromToken(pTyVar->GetTypeOrMethodDef()) == mdtMethodDef;
}

if (HasTypeParam())
{
return GetRootTypeParam().ContainsGenericVariables(methodOnly);
jkotas marked this conversation as resolved.
Show resolved Hide resolved
}

if (IsFnPtr())
{
return dac_cast<PTR_FnPtrTypeDesc>(this)->ContainsGenericVariables(methodOnly);
}

return FALSE;
}


PTR_BaseDomain TypeDesc::GetDomain()
{
CONTRACTL
Expand Down Expand Up @@ -1670,6 +1695,21 @@ FnPtrTypeDesc::IsSharedByGenericInstantiations()
return FALSE;
} // FnPtrTypeDesc::IsSharedByGenericInstantiations

BOOL
FnPtrTypeDesc::ContainsGenericVariables(BOOL methodOnly)
{
LIMITED_METHOD_DAC_CONTRACT;

for (DWORD i = 0; i <= m_NumArgs; i++)
{
if (m_RetAndArgTypes[i].ContainsGenericVariables(methodOnly))
{
return TRUE;
}
}
return FALSE;
} // FnPtrTypeDesc::ContainsGenericVariables

#ifndef DACCESS_COMPILE

// Returns TRUE if all return and argument types are externally visible.
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/vm/typedesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ class TypeDesc

BOOL IsSharedByGenericInstantiations();

BOOL ContainsGenericVariables(BOOL methodOnly);

protected:
// See methodtable.h for details of the flags with the same name there
enum
Expand Down Expand Up @@ -527,6 +529,8 @@ class FnPtrTypeDesc : public TypeDesc

BOOL IsSharedByGenericInstantiations();

BOOL ContainsGenericVariables(BOOL methodOnly);

#ifndef DACCESS_COMPILE
// Returns TRUE if all return and argument types are externally visible.
BOOL IsExternallyVisible() const;
Expand Down
24 changes: 4 additions & 20 deletions src/coreclr/vm/typehandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,26 +138,10 @@ BOOL TypeHandle::ContainsGenericVariables(BOOL methodOnly /*=FALSE*/) const
STATIC_CONTRACT_NOTHROW;
SUPPORTS_DAC;

if (HasTypeParam())
{
return GetTypeParam().ContainsGenericVariables(methodOnly);
}

if (IsGenericVariable())
{
if (!methodOnly)
return TRUE;

PTR_TypeVarTypeDesc pTyVar = dac_cast<PTR_TypeVarTypeDesc>(AsTypeDesc());
return TypeFromToken(pTyVar->GetTypeOrMethodDef()) == mdtMethodDef;
}
else if (HasInstantiation())
{
if (GetMethodTable()->ContainsGenericVariables(methodOnly))
return TRUE;
}

return FALSE;
if (IsTypeDesc())
return AsTypeDesc()->ContainsGenericVariables(methodOnly);
else
return AsMethodTable()->ContainsGenericVariables(methodOnly);
}

//@GENERICS:
Expand Down
7 changes: 7 additions & 0 deletions src/libraries/Common/tests/System/FunctionPointerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ public static unsafe void FunctionPointerReturn()
Assert.True(fcnPtr2.IsFunctionPointer);

Assert.True(fcnPtr1.IsFunctionPointerEqual(fcnPtr2));

MethodInfo m3 = t.GetMethod(nameof(FunctionPointerHolder.GenericMethodReturnValue), Bindings);
Type fcnPtr3 = m3.ReturnType;
Assert.True(fcnPtr3.IsFunctionPointer);
Assert.True(fcnPtr3.ContainsGenericParameters);
steveharter marked this conversation as resolved.
Show resolved Hide resolved
}

[Fact]
Expand Down Expand Up @@ -278,6 +283,8 @@ private unsafe class FunctionPointerHolder
public delegate* unmanaged[Stdcall, MemberFunction]<string, ref bool*, MyClass, in MyStruct, double> SeveralArguments() => default;
public delegate*<in int, out int, void> RequiredModifiers() => default;

public delegate*<T> GenericMethodReturnValue<T>() => default;

public class MyClass { }
public struct MyStruct { }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,23 @@ public sealed override bool Equals([NotNullWhen(true)] object? obj)
public sealed override bool IsGenericParameter => false;
public sealed override bool IsGenericTypeParameter => false;
public sealed override bool IsGenericMethodParameter => false;
public sealed override bool ContainsGenericParameters => IsGenericTypeDefinition;

public sealed override bool ContainsGenericParameters
{
get
{
if (_returnType.ContainsGenericParameters)
return true;

foreach (Type parameterType in _parameterTypes)
{
if (parameterType.ContainsGenericParameters)
return true;
}

return false;
}
}

protected sealed override TypeCode GetTypeCodeImpl() => TypeCode.Object;

Expand Down
10 changes: 10 additions & 0 deletions src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2048,6 +2048,16 @@ public override bool ContainsGenericParameters
if (HasElementType)
return GetElementType().ContainsGenericParameters;

if (IsFunctionPointer)
{
if (GetFunctionPointerReturnType().ContainsGenericParameters)
return true;

foreach (Type arg in GetFunctionPointerParameterTypes())
if (arg.ContainsGenericParameters)
return true;
}

return false;
}
}
Expand Down
Loading