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.IsPublic for pointer and byref types #65156

Merged
merged 11 commits into from
Feb 21, 2022
2 changes: 1 addition & 1 deletion src/coreclr/vm/runtimehandles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUN

if (typeHandle.IsTypeDesc()) {

if (typeHandle.IsGenericVariable()) {
if (typeHandle.IsGenericVariable() || typeHandle.IsByRef() || typeHandle.IsPointer() || typeHandle.IsFnPtrType()) {
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
return tdPublic;
}

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;
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved

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,10 @@ public class ClassWithDefaultMember1<T> where T : ClassWithDefaultMember1<T>
{
public int Yes;
}

public class PubilcClass
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
{
internal class InternalNestedClass { }
internal class InternalNestedGenericClass<T> { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,37 @@ public static void TestIsValueType()
return;
}

public static IEnumerable<object[]> TypeDescTypesIsPublic_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(PubilcClass.InternalNestedClass).Project().MakeByRefType(), true, false };
yield return new object[] { typeof(PubilcClass.InternalNestedClass).Project().MakePointerType(), true, false };
yield return new object[] { typeof(PubilcClass.InternalNestedClass).Project(), false, false };
yield return new object[] { typeof(PubilcClass.InternalNestedGenericClass<>).Project().MakeGenericType(typeof(PubilcClass).Project()), false, false };
yield return new object[] { typeof(PubilcClass).Project().MakeByRefType(), true, true };
yield return new object[] { typeof(PubilcClass).Project().MakePointerType(), true, true };
yield return new object[] { typeof(PubilcClass).Project(), true, true };
}

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

[Fact]
[SkipOnMono("System.TypeLoadException : Could not find type 'System.MonoFNPtrFakeClass'")]
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
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
51 changes: 51 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,56 @@ public void MakePointerType(Type type)
Assert.True(pointerType.IsPointer);
}

public static IEnumerable<object[]> TypeDescTypesIsPublic_TestData()
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
{
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.InternalNestedGenericClass<string>), false, false };
yield return new object[] { typeof(TI_BaseClass.InternalNestedGenericClass<>).MakeGenericType(typeof(string)), 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(TypeDescTypesIsPublic_TestData))]
public void TypeDescTypesIsPublic(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()
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
{
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 Expand Up @@ -1828,6 +1878,7 @@ public class PublicNestedClass1 { }
public class PublicNestedClass2 { }
private class PrivateNestedClass { } // Private, so not inherited
internal class InternalNestedClass { } // Internal members are not inherited
internal class InternalNestedGenericClass<T>{ }
protected class ProtectedNestedClass { }

public string StringProperty1 { get { return ""; } set { } }
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;
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved

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