Skip to content

Commit 78b77de

Browse files
[release/8.0-staging] Fix Type System Equivalence Checks (#106667)
* Initial fix for the type not being read bug. * Addressed initial feedback to fully fix the bug. --------- Co-authored-by: Ivan Diaz <ivdiazsa@microsoft.com>
1 parent 5ce9f84 commit 78b77de

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

src/coreclr/tools/Common/TypeSystem/Ecma/EcmaType.TypeEquivalence.cs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public partial class EcmaType
1414
private TypeIdentifierData ComputeTypeIdentifierFromGuids()
1515
{
1616
CustomAttributeValue<TypeDesc>? guidAttribute;
17+
1718
if (IsInterface && _typeDefinition.Attributes.HasFlag(TypeAttributes.Import))
1819
{
1920
// ComImport interfaces get scope from their GUID
@@ -23,6 +24,7 @@ private TypeIdentifierData ComputeTypeIdentifierFromGuids()
2324
{
2425
// other equivalent types get it from the declaring assembly
2526
var attributeHandle = this.MetadataReader.GetCustomAttributeHandle(MetadataReader.GetAssemblyDefinition().GetCustomAttributes(), "System.Runtime.InteropServices", "GuidAttribute");
27+
2628
if (attributeHandle.IsNil)
2729
return null;
2830

@@ -40,6 +42,7 @@ private TypeIdentifierData ComputeTypeIdentifierFromGuids()
4042

4143
string scope = (string)guidAttribute.Value.FixedArguments[0].Value;
4244
string name = this.Name;
45+
4346
if (this.Namespace != null)
4447
name = this.Namespace + "." + name;
4548

@@ -53,6 +56,7 @@ private TypeIdentifierData ComputeTypeIdentifierData()
5356

5457
// Check for type identifier attribute
5558
var typeIdentifierAttribute = this.GetDecodedCustomAttribute("System.Runtime.InteropServices", "TypeIdentifierAttribute");
59+
5660
if (typeIdentifierAttribute.HasValue)
5761
{
5862
// If the type has a type identifier attribute it is always considered to be type equivalent
@@ -68,28 +72,38 @@ private TypeIdentifierData ComputeTypeIdentifierData()
6872
if (typeIdentifierAttribute.Value.FixedArguments[1].Type != Context.GetWellKnownType(WellKnownType.String))
6973
return null;
7074

71-
_data = new TypeIdentifierData((string)typeIdentifierAttribute.Value.FixedArguments[0].Value, (string)typeIdentifierAttribute.Value.FixedArguments[1].Value);
72-
return _data;
75+
return new TypeIdentifierData((string)typeIdentifierAttribute.Value.FixedArguments[0].Value, (string)typeIdentifierAttribute.Value.FixedArguments[1].Value);
7376
}
74-
else
77+
78+
// In addition to the TypeIdentifierAttribute certain other types may also be opted in to type equivalence
79+
if (Context.SupportsCOMInterop)
7580
{
76-
// In addition to the TypeIdentifierAttribute certain other types may also be opted in to type equivalence
77-
if (Context.SupportsCOMInterop)
81+
// 1. The assembly is marked with ImportedFromTypeLibAttribute or PrimaryInteropAssemblyAttribute
82+
// We will verify this by checking for their attribute handles using the Metadata Reader.
83+
84+
CustomAttributeHandle importedFromTypeLibHdl = this.MetadataReader.GetCustomAttributeHandle(
85+
MetadataReader.GetAssemblyDefinition().GetCustomAttributes(),
86+
"System.Runtime.InteropServices",
87+
"ImportedFromTypeLibAttribute"
88+
);
89+
90+
CustomAttributeHandle primaryInteropAssemblyHdl = this.MetadataReader.GetCustomAttributeHandle(
91+
MetadataReader.GetAssemblyDefinition().GetCustomAttributes(),
92+
"System.Runtime.InteropServices",
93+
"PrimaryInteropAssemblyAttribute"
94+
);
95+
96+
if (!importedFromTypeLibHdl.IsNil || !primaryInteropAssemblyHdl.IsNil)
7897
{
79-
// 1. Type is within assembly marked with ImportedFromTypeLibAttribute or PrimaryInteropAssemblyAttribute
80-
if (this.HasCustomAttribute("System.Runtime.InteropServices", "ImportedFromTypeLibAttribute") || this.HasCustomAttribute("System.Runtime.InteropServices", "PrimaryInteropAssemblyAttribute"))
81-
{
82-
// This type has a TypeIdentifier attribute if it has an appropriate shape to be considered type equivalent
83-
}
84-
98+
// This type has a TypeIdentifier attribute if it has an appropriate shape to be considered type equivalent
8599
if (!TypeHasCharacteristicsRequiredToBeTypeEquivalent)
86100
return null;
87101

88-
_data = ComputeTypeIdentifierFromGuids();
102+
return ComputeTypeIdentifierFromGuids();
89103
}
90-
91-
return null;
92104
}
105+
106+
return null;
93107
}
94108

95109
public override TypeIdentifierData TypeIdentifierData

0 commit comments

Comments
 (0)