From b28623cfebaa800f42539e526d3ccba1e196dd39 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 10 Feb 2022 13:03:26 -0800 Subject: [PATCH 01/11] Fix Type.IsPublic for pointer and byref types --- src/coreclr/vm/runtimehandles.cpp | 10 ++------ src/coreclr/vm/typehandle.cpp | 20 ++++++++++++++++ src/coreclr/vm/typehandle.h | 3 +++ .../System.Reflection/tests/TypeInfoTests.cs | 23 +++++++++++++++++++ 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 362ea14986498..bdeb0e3468f71 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -806,14 +806,8 @@ FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUN TypeHandle typeHandle = refType->GetType(); - if (typeHandle.IsTypeDesc()) { - - if (typeHandle.IsGenericVariable()) { - return tdPublic; - } - - return 0; - } + if (typeHandle.IsTypeDesc()) + return typeHandle.GetElementTypeAttributes(); #ifdef FEATURE_COMINTEROP // __ComObject types are always public. diff --git a/src/coreclr/vm/typehandle.cpp b/src/coreclr/vm/typehandle.cpp index 13e59e5ffeb6f..266df3fa9478a 100644 --- a/src/coreclr/vm/typehandle.cpp +++ b/src/coreclr/vm/typehandle.cpp @@ -244,6 +244,26 @@ TypeHandle TypeHandle::GetTypeParam() const return TypeHandle(); } +// Obtain attributes of the element type from a byref or pointer type, returns tdPublic for generic type variables, 0 otherwise +INT32 TypeHandle::GetElementTypeAttributes() const +{ + LIMITED_METHOD_DAC_CONTRACT; + + if (IsGenericVariable()) + return tdPublic; + + if (IsPointer() || IsByRef()) { + TypeHandle elementType = GetTypeParam(); + + if (elementType.IsTypeDesc()) + return elementType.GetElementTypeAttributes(); + + return (INT32)elementType.GetMethodTable()->GetAttrClass(); + } + + return 0; +} + #ifndef DACCESS_COMPILE TypeHandle TypeHandle::Instantiate(Instantiation inst) const { diff --git a/src/coreclr/vm/typehandle.h b/src/coreclr/vm/typehandle.h index aa9a80a576fa4..3554a8c94c568 100644 --- a/src/coreclr/vm/typehandle.h +++ b/src/coreclr/vm/typehandle.h @@ -285,6 +285,9 @@ class TypeHandle // Obtain element type for an array, byref or pointer, returning NULL otherwise TypeHandle GetTypeParam() const; + // Obtain attributes of the element type from a byref or pointer type, returns tdPublic for generic type variables, 0 otherwise + INT32 GetElementTypeAttributes() const; + // Obtain instantiation from an instantiated type // NULL if not instantiated Instantiation GetInstantiation() const; diff --git a/src/libraries/System.Reflection/tests/TypeInfoTests.cs b/src/libraries/System.Reflection/tests/TypeInfoTests.cs index f3b9240505c69..f17de853db079 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -1173,6 +1173,28 @@ public void MakePointerType(Type type) Assert.True(pointerType.IsPointer); } + public static IEnumerable TypeDescTypesIsPublic_TestData() + { + yield return new object[] { typeof(int).MakeByRefType(), true }; + yield return new object[] { typeof(int).MakePointerType(), true }; + yield return new object[] { typeof(int).MakeArrayType(), true }; + yield return new object[] { typeof(TI_BaseClass.InternalNestedClass).MakeByRefType(), false }; + yield return new object[] { typeof(TI_BaseClass.InternalNestedClass).MakePointerType(), false }; + yield return new object[] { typeof(TI_BaseClass.InternalNestedClass).MakeArrayType(), true }; + yield return new object[] { typeof(TI_BaseClass.InternalNestedGenericClass<>).MakeGenericType(typeof(string)), false }; + yield return new object[] { typeof(TI_BaseClass).MakeByRefType(), true }; + yield return new object[] { typeof(TI_BaseClass).MakePointerType(), true }; + yield return new object[] { typeof(TI_BaseClass).MakeArrayType(), true }; + } + + [Theory] + [MemberData(nameof(TypeDescTypesIsPublic_TestData))] + public void TypeDescTypesIsPublic(Type type, bool expected) + { + Assert.Equal(expected, type.GetTypeInfo().IsPublic); + Assert.Equal(!expected, type.GetTypeInfo().IsNestedAssembly); + } + [Fact] public void MakePointerType_TypeAlreadyByRef_ThrowsTypeLoadException() { @@ -1828,6 +1850,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{ } protected class ProtectedNestedClass { } public string StringProperty1 { get { return ""; } set { } } From a47e83ff6c76d0b77649f870a8e6661c4bca5b73 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 10 Feb 2022 14:07:13 -0800 Subject: [PATCH 02/11] Add test for nested pointer --- .../System.Reflection/tests/TypeInfoTests.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Reflection/tests/TypeInfoTests.cs b/src/libraries/System.Reflection/tests/TypeInfoTests.cs index f17de853db079..0bd046e64d385 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -1191,8 +1191,16 @@ public static IEnumerable TypeDescTypesIsPublic_TestData() [MemberData(nameof(TypeDescTypesIsPublic_TestData))] public void TypeDescTypesIsPublic(Type type, bool expected) { - Assert.Equal(expected, type.GetTypeInfo().IsPublic); - Assert.Equal(!expected, type.GetTypeInfo().IsNestedAssembly); + Assert.Equal(expected, type.IsPublic); + Assert.Equal(!expected, type.IsNestedAssembly); + } + + [Fact] + public void NestedPointerIsPublic() + { + Type pointerType = typeof(int***); + Assert.True(pointerType.IsPointer); + Assert.True(pointerType.IsPublic); } [Fact] From 0afba51c53b8e3a12fca6a43dca329bb3b26bd42 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 10 Feb 2022 19:35:18 -0800 Subject: [PATCH 03/11] Apply feedback, try fix mono failure --- src/coreclr/vm/typehandle.cpp | 1 + src/mono/mono/metadata/icall.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/typehandle.cpp b/src/coreclr/vm/typehandle.cpp index 266df3fa9478a..a9b7afc94f710 100644 --- a/src/coreclr/vm/typehandle.cpp +++ b/src/coreclr/vm/typehandle.cpp @@ -253,6 +253,7 @@ INT32 TypeHandle::GetElementTypeAttributes() const return tdPublic; if (IsPointer() || IsByRef()) { + _ASSERTE(HasTypeParam()); TypeHandle elementType = GetTypeParam(); if (elementType.IsTypeDesc()) diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index ec5325bc2aa2d..cf147c4a3da72 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -1802,7 +1802,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) + if (type->type == MONO_TYPE_FNPTR) return TYPE_ATTRIBUTE_NOT_PUBLIC; MonoClass *klass = mono_class_from_mono_type_internal (type); From 78a0d9aaaef0b83a80cfd0427d3387672e6223cf Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 11 Feb 2022 00:11:47 -0800 Subject: [PATCH 04/11] Fix failures in runtime test --- .../System.Runtime/tests/System/Type/TypePropertyTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs b/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs index cf1b8d6989d9e..840f34137d4bb 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.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Sealed | TypeAttributes.Serializable | TypeAttributes.BeforeFieldInit; public override Type BaseType => null; From cadba9590b0bd86161041f5a3b0b6886f73717fa Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 11 Feb 2022 11:45:16 -0800 Subject: [PATCH 05/11] Add conditional for mono/clr test --- .../System.Runtime/tests/System/Type/TypePropertyTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs b/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs index 840f34137d4bb..f65904530d320 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs @@ -672,7 +672,8 @@ public class IntPointerTests : TypePropertyTestBase { public override Type CreateType() => typeof(int).MakePointerType(); - public override TypeAttributes Attributes => TypeAttributes.Public; + public override TypeAttributes Attributes => PlatformDetection.IsMonoRuntime ? TypeAttributes.Public : + TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Sealed | TypeAttributes.Serializable | TypeAttributes.BeforeFieldInit; public override Type BaseType => null; From 11076ec2edbcd1e0972c4811299049cf7be19c83 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Tue, 15 Feb 2022 17:40:00 -0800 Subject: [PATCH 06/11] Add tests for delegate --- .../System.Reflection/tests/TypeInfoTests.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libraries/System.Reflection/tests/TypeInfoTests.cs b/src/libraries/System.Reflection/tests/TypeInfoTests.cs index 0bd046e64d385..2c05869267eab 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -1195,6 +1195,20 @@ public void TypeDescTypesIsPublic(Type type, bool expected) Assert.Equal(!expected, type.IsNestedAssembly); } + public delegate void PublicDelegate(string str); + internal delegate void InternalDelegate(string str); + + [Fact] + public void DelegateTypesIsPublic() + { + Assert.True(typeof(Delegate).IsPublic); + Assert.True(typeof(PublicDelegate).IsNestedPublic); + Assert.True(typeof(InternalDelegate).IsNestedAssembly); + Assert.True(typeof(InternalDelegate).MakePointerType().IsNestedAssembly); + Assert.True(typeof(delegate*).IsPublic); + Assert.True(typeof(Delegate).MakePointerType().IsPublic); + } + [Fact] public void NestedPointerIsPublic() { From ccc7668789d7e3e75adbeb5cbfab92d52b356d4c Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Wed, 16 Feb 2022 23:31:54 -0800 Subject: [PATCH 07/11] Split tests, return public for function pointer on mono --- .../System.Reflection/tests/TypeInfoTests.cs | 12 +++++++++++- src/mono/mono/metadata/icall.c | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Reflection/tests/TypeInfoTests.cs b/src/libraries/System.Reflection/tests/TypeInfoTests.cs index 2c05869267eab..e328efb226e24 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -1202,11 +1202,21 @@ public void TypeDescTypesIsPublic(Type type, bool expected) 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.True(typeof(InternalDelegate).MakePointerType().IsNestedAssembly); - Assert.True(typeof(delegate*).IsPublic); + Assert.False(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] diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index cf147c4a3da72..4d9457e533761 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 (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); From a17a004197e1e6d86c680dfed89da5f1f0b09bab Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 18 Feb 2022 13:38:19 -0800 Subject: [PATCH 08/11] Ref pointer types should be public, update MLC accordingly --- src/coreclr/vm/runtimehandles.cpp | 10 ++++- src/coreclr/vm/typehandle.cpp | 21 ---------- src/coreclr/vm/typehandle.h | 3 -- .../TypeLoading/Types/RoByRefType.cs | 2 +- .../TypeLoading/Types/RoPointerType.cs | 2 +- .../src/SampleMetadata/SampleMetadata.cs | 6 +++ .../tests/src/Tests/Type/TypeTests.cs | 30 +++++++++++++ .../System.Reflection/tests/TypeInfoTests.cs | 42 +++++++++---------- .../tests/System/Type/TypePropertyTests.cs | 5 +-- src/mono/mono/metadata/icall.c | 2 +- 10 files changed, 68 insertions(+), 55 deletions(-) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index bdeb0e3468f71..d3b16afd227e8 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -806,8 +806,14 @@ FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUN TypeHandle typeHandle = refType->GetType(); - if (typeHandle.IsTypeDesc()) - return typeHandle.GetElementTypeAttributes(); + if (typeHandle.IsTypeDesc()) { + + if (typeHandle.IsGenericVariable() || typeHandle.IsByRef() || typeHandle.IsPointer() || typeHandle.IsFnPtrType()) { + return tdPublic; + } + + return 0; + } #ifdef FEATURE_COMINTEROP // __ComObject types are always public. diff --git a/src/coreclr/vm/typehandle.cpp b/src/coreclr/vm/typehandle.cpp index a9b7afc94f710..13e59e5ffeb6f 100644 --- a/src/coreclr/vm/typehandle.cpp +++ b/src/coreclr/vm/typehandle.cpp @@ -244,27 +244,6 @@ TypeHandle TypeHandle::GetTypeParam() const return TypeHandle(); } -// Obtain attributes of the element type from a byref or pointer type, returns tdPublic for generic type variables, 0 otherwise -INT32 TypeHandle::GetElementTypeAttributes() const -{ - LIMITED_METHOD_DAC_CONTRACT; - - if (IsGenericVariable()) - return tdPublic; - - if (IsPointer() || IsByRef()) { - _ASSERTE(HasTypeParam()); - TypeHandle elementType = GetTypeParam(); - - if (elementType.IsTypeDesc()) - return elementType.GetElementTypeAttributes(); - - return (INT32)elementType.GetMethodTable()->GetAttrClass(); - } - - return 0; -} - #ifndef DACCESS_COMPILE TypeHandle TypeHandle::Instantiate(Instantiation inst) const { diff --git a/src/coreclr/vm/typehandle.h b/src/coreclr/vm/typehandle.h index 3554a8c94c568..aa9a80a576fa4 100644 --- a/src/coreclr/vm/typehandle.h +++ b/src/coreclr/vm/typehandle.h @@ -285,9 +285,6 @@ class TypeHandle // Obtain element type for an array, byref or pointer, returning NULL otherwise TypeHandle GetTypeParam() const; - // Obtain attributes of the element type from a byref or pointer type, returns tdPublic for generic type variables, 0 otherwise - INT32 GetElementTypeAttributes() const; - // Obtain instantiation from an instantiated type // NULL if not instantiated Instantiation GetInstantiation() const; 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..24b77cd61a79d 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,10 @@ public class ClassWithDefaultMember1 where T : ClassWithDefaultMember1 { public int Yes; } + + public class PubilcClass + { + internal class InternalNestedClass { } + internal class InternalNestedGenericClass { } + } } 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..f7c2358d4b53a 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 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] + 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 e328efb226e24..e073cac8b24e7 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -1175,24 +1175,28 @@ public void MakePointerType(Type type) public static IEnumerable TypeDescTypesIsPublic_TestData() { - yield return new object[] { typeof(int).MakeByRefType(), true }; - yield return new object[] { typeof(int).MakePointerType(), true }; - yield return new object[] { typeof(int).MakeArrayType(), true }; - yield return new object[] { typeof(TI_BaseClass.InternalNestedClass).MakeByRefType(), false }; - yield return new object[] { typeof(TI_BaseClass.InternalNestedClass).MakePointerType(), false }; - yield return new object[] { typeof(TI_BaseClass.InternalNestedClass).MakeArrayType(), true }; - yield return new object[] { typeof(TI_BaseClass.InternalNestedGenericClass<>).MakeGenericType(typeof(string)), false }; - yield return new object[] { typeof(TI_BaseClass).MakeByRefType(), true }; - yield return new object[] { typeof(TI_BaseClass).MakePointerType(), true }; - yield return new object[] { typeof(TI_BaseClass).MakeArrayType(), true }; + 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.InternalNestedGenericClass), 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), true, true }; } [Theory] [MemberData(nameof(TypeDescTypesIsPublic_TestData))] - public void TypeDescTypesIsPublic(Type type, bool expected) + public void TypeDescTypesIsPublic(Type type, bool isPublic, bool isVisible) { - Assert.Equal(expected, type.IsPublic); - Assert.Equal(!expected, type.IsNestedAssembly); + Assert.Equal(isPublic, type.IsPublic); + Assert.Equal(!isPublic, type.IsNestedAssembly); + Assert.Equal(isVisible, type.IsVisible); } public delegate void PublicDelegate(string str); @@ -1206,8 +1210,8 @@ public void DelegateTypesIsPublic() Assert.True(typeof(PublicDelegate).IsNestedPublic); Assert.True(typeof(InternalDelegate).IsNestedAssembly); Assert.False(typeof(InternalDelegate).IsPublic); - Assert.True(typeof(InternalDelegate).MakePointerType().IsNestedAssembly); - Assert.False(typeof(InternalDelegate).MakePointerType().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); } @@ -1219,14 +1223,6 @@ public void FunctionPointerTypeIsPublic() Assert.True(typeof(delegate*).MakePointerType().IsPublic); } - [Fact] - public void NestedPointerIsPublic() - { - Type pointerType = typeof(int***); - Assert.True(pointerType.IsPointer); - Assert.True(pointerType.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 f65904530d320..04dcbafe1f166 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs @@ -672,8 +672,7 @@ public class IntPointerTests : TypePropertyTestBase { public override Type CreateType() => typeof(int).MakePointerType(); - public override TypeAttributes Attributes => PlatformDetection.IsMonoRuntime ? TypeAttributes.Public : - TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Sealed | TypeAttributes.Serializable | TypeAttributes.BeforeFieldInit; + public override TypeAttributes Attributes => TypeAttributes.Public; public override Type BaseType => null; @@ -690,7 +689,7 @@ public class IntRefTests : TypePropertyTestBase { public override Type CreateType() => typeof(int).MakeByRefType(); - public override TypeAttributes Attributes => TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Sealed | TypeAttributes.Serializable | TypeAttributes.BeforeFieldInit; + 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 4d9457e533761..1c86818363bf7 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -1802,7 +1802,7 @@ ves_icall_RuntimeTypeHandle_GetAttributes (MonoQCallTypeHandle type_handle) { MonoType *type = type_handle.type; - if (type->type == MONO_TYPE_FNPTR) + if (m_type_is_byref (type) || type->type == MONO_TYPE_PTR || type->type == MONO_TYPE_FNPTR) return TYPE_ATTRIBUTE_PUBLIC; MonoClass *klass = mono_class_from_mono_type_internal (type); From cb3724208d54c724df882beebd1e79575fd2935b Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 18 Feb 2022 16:44:45 -0800 Subject: [PATCH 09/11] MLC function pointer do not work on mono --- .../tests/src/Tests/Type/TypeTests.cs | 1 + 1 file changed, 1 insertion(+) 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 f7c2358d4b53a..eb9edc5bcaeb9 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 @@ -488,6 +488,7 @@ public static void TypeDescTypesIsPublic(Type type, bool isPublic, bool isVisibl } [Fact] + [SkipOnMono("System.TypeLoadException : Could not find type 'System.MonoFNPtrFakeClass'")] public static void FunctionPointerTypeIsPublic() { Assert.True(typeof(delegate*).Project().IsPublic); From f2c5c37760a5569375993b94d11ca8c6f1131403 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Sun, 20 Feb 2022 22:25:05 -0800 Subject: [PATCH 10/11] Remove unnecessary condition, update aot --- .../Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs | 2 +- src/coreclr/vm/runtimehandles.cpp | 7 +------ 2 files changed, 2 insertions(+), 7 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 d3b16afd227e8..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() || typeHandle.IsByRef() || typeHandle.IsPointer() || typeHandle.IsFnPtrType()) { - return tdPublic; - } - - return 0; + return tdPublic; } #ifdef FEATURE_COMINTEROP From 308c613ac53264605893de07e0a8b8fde6082837 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 21 Feb 2022 09:19:39 -0800 Subject: [PATCH 11/11] Rename test, remove unrelated case, fix typo --- .../src/SampleMetadata/SampleMetadata.cs | 3 +-- .../tests/src/Tests/Type/TypeTests.cs | 21 +++++++++---------- .../System.Reflection/tests/TypeInfoTests.cs | 9 +++----- 3 files changed, 14 insertions(+), 19 deletions(-) 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 24b77cd61a79d..52075da13b5ff 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs @@ -554,9 +554,8 @@ public class ClassWithDefaultMember1 where T : ClassWithDefaultMember1 public int Yes; } - public class PubilcClass + public class PublicClass { internal class InternalNestedClass { } - internal class InternalNestedGenericClass { } } } 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 eb9edc5bcaeb9..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,23 +464,22 @@ public static void TestIsValueType() return; } - public static IEnumerable TypeDescTypesIsPublic_TestData() + 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(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 }; + 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(TypeDescTypesIsPublic_TestData))] - public static void TypeDescTypesIsPublic(Type type, bool isPublic, bool isVisible) + [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); @@ -488,7 +487,7 @@ public static void TypeDescTypesIsPublic(Type type, bool isPublic, bool isVisibl } [Fact] - [SkipOnMono("System.TypeLoadException : Could not find type 'System.MonoFNPtrFakeClass'")] + [ActiveIssue("https://github.com/dotnet/runtime/issues/11354")] public static void FunctionPointerTypeIsPublic() { Assert.True(typeof(delegate*).Project().IsPublic); diff --git a/src/libraries/System.Reflection/tests/TypeInfoTests.cs b/src/libraries/System.Reflection/tests/TypeInfoTests.cs index e073cac8b24e7..7674c5a198276 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -1173,7 +1173,7 @@ public void MakePointerType(Type type) Assert.True(pointerType.IsPointer); } - public static IEnumerable TypeDescTypesIsPublic_TestData() + public static IEnumerable ByRefPonterTypes_IsPublicIsVisible_TestData() { yield return new object[] { typeof(int).MakeByRefType(), true, true }; yield return new object[] { typeof(int).MakePointerType(), true, true }; @@ -1183,16 +1183,14 @@ public static IEnumerable TypeDescTypesIsPublic_TestData() 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.InternalNestedGenericClass), 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), true, true }; } [Theory] - [MemberData(nameof(TypeDescTypesIsPublic_TestData))] - public void TypeDescTypesIsPublic(Type type, bool isPublic, bool isVisible) + [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); @@ -1878,7 +1876,6 @@ public class PublicNestedClass1 { } public class PublicNestedClass2 { } private class PrivateNestedClass { } // Private, so not inherited internal class InternalNestedClass { } // Internal members are not inherited - internal class InternalNestedGenericClass{ } protected class ProtectedNestedClass { } public string StringProperty1 { get { return ""; } set { } }