Skip to content

Commit

Permalink
Fix Type.IsPublic for pointer and byref types (#65156)
Browse files Browse the repository at this point in the history
  • Loading branch information
buyaa-n committed Feb 21, 2022
1 parent cacb3bf commit 3e01d11
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public sealed override int MetadataToken
protected override TypeAttributes GetAttributeFlagsImpl()
{
Debug.Assert(IsByRef || IsPointer);
return TypeAttributes.AnsiClass;
return TypeAttributes.Public;
}

protected sealed override int InternalGetHashCode()
Expand Down
7 changes: 1 addition & 6 deletions src/coreclr/vm/runtimehandles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -807,12 +807,7 @@ FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUN
TypeHandle typeHandle = refType->GetType();

if (typeHandle.IsTypeDesc()) {

if (typeHandle.IsGenericVariable()) {
return tdPublic;
}

return 0;
return tdPublic;
}

#ifdef FEATURE_COMINTEROP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal RoByRefType(RoType elementType)

public sealed override int GetArrayRank() => throw new ArgumentException(SR.Argument_HasToBeArrayClass);

protected sealed override TypeAttributes ComputeAttributeFlags() => TypeAttributes.AnsiClass;
protected sealed override TypeAttributes ComputeAttributeFlags() => TypeAttributes.Public;

protected sealed override string Suffix => "&";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal RoPointerType(RoType elementType)

public sealed override int GetArrayRank() => throw new ArgumentException(SR.Argument_HasToBeArrayClass);

protected sealed override TypeAttributes ComputeAttributeFlags() => TypeAttributes.AnsiClass;
protected sealed override TypeAttributes ComputeAttributeFlags() => TypeAttributes.Public;

protected sealed override string Suffix => "*";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,4 +553,9 @@ public class ClassWithDefaultMember1<T> where T : ClassWithDefaultMember1<T>
{
public int Yes;
}

public class PublicClass
{
internal class InternalNestedClass { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,36 @@ public static void TestIsValueType()
return;
}

public static IEnumerable<object[]> ByRefPonterTypes_IsPublicIsVisible_TestData()
{
yield return new object[] { typeof(int).Project().MakeByRefType(), true, true };
yield return new object[] { typeof(int).Project().MakePointerType(), true, true };
yield return new object[] { typeof(int).Project(), true, true };
yield return new object[] { typeof(SampleMetadata.PublicClass.InternalNestedClass).Project().MakeByRefType(), true, false };
yield return new object[] { typeof(SampleMetadata.PublicClass.InternalNestedClass).Project().MakePointerType(), true, false };
yield return new object[] { typeof(SampleMetadata.PublicClass.InternalNestedClass).Project(), false, false };
yield return new object[] { typeof(SampleMetadata.PublicClass).Project().MakeByRefType(), true, true };
yield return new object[] { typeof(SampleMetadata.PublicClass).Project().MakePointerType(), true, true };
yield return new object[] { typeof(SampleMetadata.PublicClass).Project(), true, true };
}

[Theory]
[MemberData(nameof(ByRefPonterTypes_IsPublicIsVisible_TestData))]
public static void ByRefPonterTypes_IsPublicIsVisible(Type type, bool isPublic, bool isVisible)
{
Assert.Equal(isPublic, type.IsPublic);
Assert.Equal(!isPublic, type.IsNestedAssembly);
Assert.Equal(isVisible, type.IsVisible);
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/11354")]
public static void FunctionPointerTypeIsPublic()
{
Assert.True(typeof(delegate*<string, int>).Project().IsPublic);
Assert.True(typeof(delegate*<string, int>).Project().MakePointerType().IsPublic);
}

[Fact]
public static void TestMethodSelection1()
{
Expand Down
48 changes: 48 additions & 0 deletions src/libraries/System.Reflection/tests/TypeInfoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,54 @@ public void MakePointerType(Type type)
Assert.True(pointerType.IsPointer);
}

public static IEnumerable<object[]> ByRefPonterTypes_IsPublicIsVisible_TestData()
{
yield return new object[] { typeof(int).MakeByRefType(), true, true };
yield return new object[] { typeof(int).MakePointerType(), true, true };
yield return new object[] { typeof(List<int>), true, true };
yield return new object[] { typeof(int), true, true };
yield return new object[] { typeof(TI_BaseClass.InternalNestedClass).MakeByRefType(), true, false };
yield return new object[] { typeof(TI_BaseClass.InternalNestedClass).MakePointerType(), true, false };
yield return new object[] { typeof(List<TI_BaseClass.InternalNestedClass>), true, false };
yield return new object[] { typeof(TI_BaseClass.InternalNestedClass), false, false };
yield return new object[] { typeof(TI_BaseClass).MakeByRefType(), true, true };
yield return new object[] { typeof(TI_BaseClass).MakePointerType(), true, true };
yield return new object[] { typeof(List<TI_BaseClass>), true, true };
}

[Theory]
[MemberData(nameof(ByRefPonterTypes_IsPublicIsVisible_TestData))]
public void ByRefPonterTypesTypes_IsPublicIsVisible(Type type, bool isPublic, bool isVisible)
{
Assert.Equal(isPublic, type.IsPublic);
Assert.Equal(!isPublic, type.IsNestedAssembly);
Assert.Equal(isVisible, type.IsVisible);
}

public delegate void PublicDelegate(string str);
internal delegate void InternalDelegate(string str);

[Fact]
public void DelegateTypesIsPublic()
{
Assert.True(typeof(Delegate).IsPublic);
Assert.False(typeof(Delegate).IsNotPublic);
Assert.True(typeof(PublicDelegate).IsNestedPublic);
Assert.True(typeof(InternalDelegate).IsNestedAssembly);
Assert.False(typeof(InternalDelegate).IsPublic);
Assert.False(typeof(InternalDelegate).MakePointerType().IsNestedAssembly);
Assert.True(typeof(InternalDelegate).MakePointerType().IsPublic);
Assert.True(typeof(Delegate).MakePointerType().IsPublic);
Assert.False(typeof(Delegate).MakePointerType().IsNotPublic);
}

[Fact]
public void FunctionPointerTypeIsPublic()
{
Assert.True(typeof(delegate*<string, int>).IsPublic);
Assert.True(typeof(delegate*<string, int>).MakePointerType().IsPublic);
}

[Fact]
public void MakePointerType_TypeAlreadyByRef_ThrowsTypeLoadException()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ public class IntPointerTests : TypePropertyTestBase
{
public override Type CreateType() => typeof(int).MakePointerType();

public override TypeAttributes Attributes => TypeAttributes.Class;
public override TypeAttributes Attributes => TypeAttributes.Public;

public override Type BaseType => null;

Expand All @@ -689,7 +689,7 @@ public class IntRefTests : TypePropertyTestBase
{
public override Type CreateType() => typeof(int).MakeByRefType();

public override TypeAttributes Attributes => TypeAttributes.Class;
public override TypeAttributes Attributes => TypeAttributes.Public;

public override Type BaseType => null;

Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/metadata/icall.c
Original file line number Diff line number Diff line change
Expand Up @@ -1803,7 +1803,7 @@ ves_icall_RuntimeTypeHandle_GetAttributes (MonoQCallTypeHandle type_handle)
MonoType *type = type_handle.type;

if (m_type_is_byref (type) || type->type == MONO_TYPE_PTR || type->type == MONO_TYPE_FNPTR)
return TYPE_ATTRIBUTE_NOT_PUBLIC;
return TYPE_ATTRIBUTE_PUBLIC;

MonoClass *klass = mono_class_from_mono_type_internal (type);
return mono_class_get_flags (klass);
Expand Down

0 comments on commit 3e01d11

Please sign in to comment.