Skip to content

Commit 25906e9

Browse files
committed
Preserve all InternalsVisibleTo attributes in ILLink Trimmer
Removes previous special handling to only keep IVT attributes for assemblies that were resolvable and marked at link time. This behaviour could cause a noticeable difference in behaviour at runtime without emitting any trim analysis warnings while providing no mechanism to retain the attributes. The removal of these attributes provides only a neglible size reduction. Fixes #92582
1 parent 89aae24 commit 25906e9

File tree

4 files changed

+42
-55
lines changed

4 files changed

+42
-55
lines changed

src/tools/illink/src/linker/Linker.Steps/MarkStep.cs

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ protected LinkContext Context {
6262
protected Queue<(MethodDefinition, DependencyInfo, MessageOrigin)> _methods;
6363
protected HashSet<(MethodDefinition, MarkScopeStack.Scope)> _virtual_methods;
6464
protected Queue<AttributeProviderPair> _assemblyLevelAttributes;
65-
readonly List<AttributeProviderPair> _ivt_attributes;
6665
protected Queue<(AttributeProviderPair, DependencyInfo, MarkScopeStack.Scope)> _lateMarkedAttributes;
6766
protected List<(TypeDefinition, MarkScopeStack.Scope)> _typesWithInterfaces;
6867
protected HashSet<AssemblyDefinition> _dynamicInterfaceCastableImplementationTypesDiscovered;
@@ -222,7 +221,6 @@ public MarkStep ()
222221
_methods = new Queue<(MethodDefinition, DependencyInfo, MessageOrigin)> ();
223222
_virtual_methods = new HashSet<(MethodDefinition, MarkScopeStack.Scope)> ();
224223
_assemblyLevelAttributes = new Queue<AttributeProviderPair> ();
225-
_ivt_attributes = new List<AttributeProviderPair> ();
226224
_lateMarkedAttributes = new Queue<(AttributeProviderPair, DependencyInfo, MarkScopeStack.Scope)> ();
227225
_typesWithInterfaces = new List<(TypeDefinition, MarkScopeStack.Scope)> ();
228226
_dynamicInterfaceCastableImplementationTypesDiscovered = new HashSet<AssemblyDefinition> ();
@@ -288,42 +286,6 @@ protected virtual void Complete ()
288286
}
289287
}
290288

291-
bool ProcessInternalsVisibleAttributes ()
292-
{
293-
bool marked_any = false;
294-
foreach (var attr in _ivt_attributes) {
295-
296-
var provider = attr.Provider;
297-
Debug.Assert (attr.Provider is ModuleDefinition or AssemblyDefinition);
298-
var assembly = (provider is ModuleDefinition module) ? module.Assembly : provider as AssemblyDefinition;
299-
300-
using var assemblyScope = ScopeStack.PushLocalScope (new MessageOrigin (assembly));
301-
302-
if (!Annotations.IsMarked (attr.Attribute) && IsInternalsVisibleAttributeAssemblyMarked (attr.Attribute)) {
303-
MarkCustomAttribute (attr.Attribute, new DependencyInfo (DependencyKind.AssemblyOrModuleAttribute, attr.Provider));
304-
marked_any = true;
305-
}
306-
}
307-
308-
return marked_any;
309-
310-
bool IsInternalsVisibleAttributeAssemblyMarked (CustomAttribute ca)
311-
{
312-
System.Reflection.AssemblyName an;
313-
try {
314-
an = new System.Reflection.AssemblyName ((string) ca.ConstructorArguments[0].Value);
315-
} catch {
316-
return false;
317-
}
318-
319-
var assembly = Context.GetLoadedAssembly (an.Name!);
320-
if (assembly == null)
321-
return false;
322-
323-
return Annotations.IsMarked (assembly.MainModule);
324-
}
325-
}
326-
327289
static bool TypeIsDynamicInterfaceCastableImplementation (TypeDefinition type)
328290
{
329291
if (!type.IsInterface || !type.HasInterfaces || !type.HasCustomAttributes)
@@ -416,8 +378,7 @@ void Process ()
416378
ProcessMarkedPending () ||
417379
ProcessLazyAttributes () ||
418380
ProcessLateMarkedAttributes () ||
419-
MarkFullyPreservedAssemblies () ||
420-
ProcessInternalsVisibleAttributes ()) ;
381+
MarkFullyPreservedAssemblies ()) ;
421382

422383
ProcessPendingTypeChecks ();
423384
}
@@ -1170,6 +1131,9 @@ protected virtual bool ShouldMarkCustomAttribute (CustomAttribute ca, ICustomAtt
11701131
case "System.Runtime.InteropServices.InterfaceTypeAttribute":
11711132
case "System.Runtime.InteropServices.GuidAttribute":
11721133
return true;
1134+
// May be implicitly used by the runtime
1135+
case "System.Runtime.CompilerServices.InternalsVisibleToAttribute":
1136+
return true;
11731137
}
11741138

11751139
TypeDefinition? type = Context.Resolve (attr_type);
@@ -1547,10 +1511,7 @@ bool ProcessLazyAttributes ()
15471511
if (IsAttributeRemoved (customAttribute, resolved.DeclaringType) && Annotations.GetAction (CustomAttributeSource.GetAssemblyFromCustomAttributeProvider (assemblyLevelAttribute.Provider)) == AssemblyAction.Link)
15481512
continue;
15491513

1550-
if (customAttribute.AttributeType.IsTypeOf ("System.Runtime.CompilerServices", "InternalsVisibleToAttribute") && !Annotations.IsMarked (customAttribute)) {
1551-
_ivt_attributes.Add (assemblyLevelAttribute);
1552-
continue;
1553-
} else if (!ShouldMarkTopLevelCustomAttribute (assemblyLevelAttribute, resolved)) {
1514+
if (!ShouldMarkTopLevelCustomAttribute (assemblyLevelAttribute, resolved)) {
15541515
skippedItems.Add (assemblyLevelAttribute);
15551516
continue;
15561517
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#if IVT
2+
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo ("missing")]
3+
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo ("test-with-key, PublicKey=00240000")]
4+
#endif
5+
6+
namespace Mono.Linker.Tests.Cases.Attributes.Dependencies;
7+
8+
public class IVTUnusedLib;
Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
using System.Runtime.CompilerServices;
2+
using Mono.Linker.Tests.Cases.Attributes.Dependencies;
23
using Mono.Linker.Tests.Cases.Expectations.Assertions;
34
using Mono.Linker.Tests.Cases.Expectations.Metadata;
45

5-
#if IVT
6-
[assembly: InternalsVisibleTo ("missing")]
7-
[assembly: InternalsVisibleTo ("test-with-key, PublicKey=00240000")]
6+
namespace Mono.Linker.Tests.Cases.Attributes;
87

9-
#endif
10-
11-
namespace Mono.Linker.Tests.Cases.Attributes
8+
[SetupCompileBefore ("lib.dll", ["Dependencies/IVTUnused_Lib.cs"], defines: ["IVT"])]
9+
[KeptAssembly ("lib.dll")]
10+
[KeptTypeInAssembly ("lib.dll", typeof(IVTUnusedLib))]
11+
[KeptAttributeInAssembly ("lib.dll", typeof (InternalsVisibleToAttribute))]
12+
class IVTUnused
1213
{
13-
[Define ("IVT")]
14-
class IVTUnused
14+
static void Main ()
1515
{
16-
static void Main ()
17-
{
18-
}
16+
_ = new IVTUnusedLib ();
1917
}
2018
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Runtime.CompilerServices;
2+
using Mono.Linker.Tests.Cases.Attributes.Dependencies;
3+
using Mono.Linker.Tests.Cases.Expectations.Assertions;
4+
using Mono.Linker.Tests.Cases.Expectations.Metadata;
5+
6+
namespace Mono.Linker.Tests.Cases.Attributes;
7+
8+
[SetupCompileBefore ("lib.dll", ["Dependencies/IVTUnused_Lib.cs"], defines: ["IVT"])]
9+
[KeptAssembly ("lib.dll")]
10+
[KeptTypeInAssembly ("lib.dll", typeof(IVTUnusedLib))]
11+
[KeptAttributeInAssembly ("lib.dll", typeof (InternalsVisibleToAttribute))]
12+
13+
[SetupLinkerArgument("--used-attrs-only", "true")]
14+
class IVTUnusedKeptWhenKeepingUsedAttributesOnly
15+
{
16+
static void Main ()
17+
{
18+
_ = new IVTUnusedLib ();
19+
}
20+
}

0 commit comments

Comments
 (0)