From 3e01d11fd1722450d326f90b4913f3831ce132bb Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 21 Feb 2022 15:35:46 -0800 Subject: [PATCH] Fix Type.IsPublic for pointer and byref types (#65156) --- .../TypeInfos/RuntimeHasElementTypeInfo.cs | 2 +- src/coreclr/vm/runtimehandles.cpp | 7 +-- .../TypeLoading/Types/RoByRefType.cs | 2 +- .../TypeLoading/Types/RoPointerType.cs | 2 +- .../src/SampleMetadata/SampleMetadata.cs | 5 ++ .../tests/src/Tests/Type/TypeTests.cs | 30 ++++++++++++ .../System.Reflection/tests/TypeInfoTests.cs | 48 +++++++++++++++++++ .../tests/System/Type/TypePropertyTests.cs | 4 +- src/mono/mono/metadata/icall.c | 2 +- 9 files changed, 90 insertions(+), 12 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs index 299cab3b9d759..f0dbbac9761da 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs @@ -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() diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 362ea14986498..fdb3a19cfd05d 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -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 diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoByRefType.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoByRefType.cs index f5defdcf0dd6f..c30397c39c76c 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoByRefType.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoByRefType.cs @@ -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 => "&"; diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoPointerType.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoPointerType.cs index 727aced519ba3..bf1657e4db3d4 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoPointerType.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoPointerType.cs @@ -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 => "*"; diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs index 15d46738c3516..52075da13b5ff 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs @@ -553,4 +553,9 @@ public class ClassWithDefaultMember1 where T : ClassWithDefaultMember1 { public int Yes; } + + public class PublicClass + { + internal class InternalNestedClass { } + } } diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs index bb9f1775d2fff..c0292e2999957 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs @@ -464,6 +464,36 @@ public static void TestIsValueType() return; } + public static IEnumerable 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*).Project().IsPublic); + Assert.True(typeof(delegate*).Project().MakePointerType().IsPublic); + } + [Fact] public static void TestMethodSelection1() { diff --git a/src/libraries/System.Reflection/tests/TypeInfoTests.cs b/src/libraries/System.Reflection/tests/TypeInfoTests.cs index a9b4292c2fb4b..e7d2977ec56b5 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -1173,6 +1173,54 @@ public void MakePointerType(Type type) Assert.True(pointerType.IsPointer); } + public static IEnumerable 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), 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), 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), 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*).IsPublic); + Assert.True(typeof(delegate*).MakePointerType().IsPublic); + } + [Fact] public void MakePointerType_TypeAlreadyByRef_ThrowsTypeLoadException() { diff --git a/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs b/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs index cf1b8d6989d9e..04dcbafe1f166 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs @@ -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; @@ -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; diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index ec5325bc2aa2d..1c86818363bf7 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -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);