diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs index 3b87c62452fd28..730e43e77560de 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs @@ -80,6 +80,12 @@ public bool InterproceduralAnalyze() return succeeded; } + // Delegate types with default parameter values produce operation blocks whose + // OwningSymbol is the delegate INamedTypeSymbol. These blocks contain only + // simple constant initializers with no interesting dataflow, so skip them. + if (Context.OwningSymbol is INamedTypeSymbol { TypeKind: TypeKind.Delegate }) + return succeeded; + Debug.Assert(Context.OwningSymbol is not IMethodSymbol methodSymbol || methodSymbol.MethodKind is not (MethodKind.LambdaMethod or MethodKind.LocalFunction)); var startMethod = new MethodBodyValue(Context.OwningSymbol, Context.GetControlFlowGraph(OperationBlock)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs index f719ae746f7434..4daf4aec7f545e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs @@ -890,6 +890,11 @@ class DelegateCreation static event Action Event; + // Delegate with a default parameter value. + // The default parameter generates an operation block whose OwningSymbol + // is the delegate type (INamedTypeSymbol), not a method. + delegate void DelegateWithDefaultParameter(Type type = null); + static void TestField() { var d = new UnannotatedDelegate(field);