diff --git a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs index 8a0c9402cb54cd..68fcf7b41178e6 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -69,6 +70,7 @@ private IDictionary CreateDataContainer() public MethodBase? TargetSite { + [RequiresUnreferencedCode("Metadata for the method might be incomplete or removed")] get { if (_exceptionMethod != null) @@ -85,13 +87,17 @@ public MethodBase? TargetSite } } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "The API will return null if the metadata for current method cannot be established.")] private string? CreateSourceName() { StackTrace st = new StackTrace(this, fNeedFileInfo: false); if (st.FrameCount > 0) { StackFrame sf = st.GetFrame(0)!; - MethodBase method = sf.GetMethod()!; + MethodBase? method = sf.GetMethod(); + if (method == null) + return null; Module module = method.Module; diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs index 7cd1966cb35c80..89829cba3479e5 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; using System.Threading; @@ -36,6 +37,7 @@ public abstract partial class MethodBase : MemberInfo return RuntimeType.GetMethodBase(declaringType.GetRuntimeType(), handle.GetMethodInfo()); } + [RequiresUnreferencedCode("Metadata for the method might be incomplete or removed")] [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public static MethodBase? GetCurrentMethod() { diff --git a/src/libraries/System.Diagnostics.StackTrace/ref/System.Diagnostics.StackTrace.cs b/src/libraries/System.Diagnostics.StackTrace/ref/System.Diagnostics.StackTrace.cs index b3cb0bdb3b33e1..0efbf90bb1da10 100644 --- a/src/libraries/System.Diagnostics.StackTrace/ref/System.Diagnostics.StackTrace.cs +++ b/src/libraries/System.Diagnostics.StackTrace/ref/System.Diagnostics.StackTrace.cs @@ -19,6 +19,7 @@ public StackFrame(string? fileName, int lineNumber, int colNumber) { } public virtual int GetFileLineNumber() { throw null; } public virtual string? GetFileName() { throw null; } public virtual int GetILOffset() { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Metadata for the method might be incomplete or removed")] public virtual System.Reflection.MethodBase? GetMethod() { throw null; } public virtual int GetNativeOffset() { throw null; } public override string ToString() { throw null; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Contracts/Contracts.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Contracts/Contracts.cs index 49445f16b2d071..fd347add1795d9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Contracts/Contracts.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Contracts/Contracts.cs @@ -619,6 +619,9 @@ public static void EndContractBlock() { } /// This method is used internally to trigger a failure indicating to the "programmer" that they are using the interface incorrectly. /// It is NEVER used to indicate failure of actual contracts at runtime. /// + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "StackFrame.GetMethod is only used to help diagnosing incorrect use of contracts. " + + "It handles missing or incomplete metadata.")] private static void AssertMustUseRewriter(ContractFailureKind kind, string contractKind) { // For better diagnostics, report which assembly is at fault. Walk up stack and diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs index 5f19d27dfc057d..0b2724bb6c4999 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Text; using System.Reflection; using System.Runtime.CompilerServices; @@ -136,6 +137,7 @@ public StackFrame(string? fileName, int lineNumber, int colNumber) /// /// Returns the method the frame is executing /// + [RequiresUnreferencedCode("Metadata for the method might be incomplete or removed")] public virtual MethodBase? GetMethod() { return _method; diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrameExtensions.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrameExtensions.cs index df4dcf166fd2f0..500f2783ff3ca1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrameExtensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrameExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; namespace System.Diagnostics { @@ -12,6 +13,8 @@ public static bool HasNativeImage(this StackFrame stackFrame) return stackFrame.GetNativeImageBase() != IntPtr.Zero; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "StackFrame.GetMethod is used to establish if method is available.")] public static bool HasMethod(this StackFrame stackFrame) { return stackFrame.GetMethod() != null; diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs index 0e215f478dde63..52472948bfee2b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs @@ -203,6 +203,8 @@ internal string ToString(TraceFormat traceFormat) } #if !CORERT + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "ToString is best effort when it comes to available information.")] internal void ToString(TraceFormat traceFormat, StringBuilder sb) { // Passing a default string for "at" in case SR.UsingResourceKeys() is true @@ -301,8 +303,12 @@ internal void ToString(TraceFormat traceFormat, StringBuilder sb) if (pi[j].ParameterType != null) typeName = pi[j].ParameterType.Name; sb.Append(typeName); - sb.Append(' '); - sb.Append(pi[j].Name); + string? parameterName = pi[j].Name; + if (parameterName != null) + { + sb.Append(' '); + sb.Append(parameterName); + } } sb.Append(')'); } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index a7042b6bb17357..ecd536be23436d 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -2839,7 +2839,7 @@ public Exception(string? message, System.Exception? innerException) { } public virtual string Message { get { throw null; } } public virtual string? Source { get { throw null; } set { } } public virtual string? StackTrace { get { throw null; } } - public System.Reflection.MethodBase? TargetSite { get { throw null; } } + public System.Reflection.MethodBase? TargetSite { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Metadata for the method might be incomplete or removed")] get { throw null; } } [System.ObsoleteAttribute("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId = "SYSLIB0011", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] protected event System.EventHandler? SerializeObjectState { add { } remove { } } public virtual System.Exception GetBaseException() { throw null; } @@ -11873,6 +11873,7 @@ protected MethodBase() { } public abstract System.RuntimeMethodHandle MethodHandle { get; } public virtual System.Reflection.MethodImplAttributes MethodImplementationFlags { get { throw null; } } public override bool Equals(object? obj) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Metadata for the method might be incomplete or removed")] public static System.Reflection.MethodBase? GetCurrentMethod() { throw null; } public virtual System.Type[] GetGenericArguments() { throw null; } public override int GetHashCode() { throw null; } diff --git a/src/mono/System.Private.CoreLib/src/System/Exception.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Exception.Mono.cs index a8fda176114d66..23f00cfea877d1 100644 --- a/src/mono/System.Private.CoreLib/src/System/Exception.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Exception.Mono.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.InteropServices; using System.Diagnostics.Tracing; @@ -50,6 +51,7 @@ public DispatchState(MonoStackFrame[]? stackFrames) public MethodBase? TargetSite { + [RequiresUnreferencedCode("Metadata for the method might be incomplete or removed")] get { StackTrace st = new StackTrace(this, true); @@ -107,6 +109,8 @@ private bool CanSetRemoteStackTrace() return true; // mono runtime doesn't have immutable agile exceptions, always return true } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "The API will return null if the metadata for current method cannot be established.")] private string? CreateSourceName() { var st = new StackTrace(this, fNeedFileInfo: false); @@ -114,6 +118,8 @@ private bool CanSetRemoteStackTrace() { StackFrame sf = st.GetFrame(0)!; MethodBase? method = sf.GetMethod(); + if (method == null) + return null; Module? module = method?.Module; RuntimeModule? rtModule = module as RuntimeModule; diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/MethodBase.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/MethodBase.Mono.cs index 0ae9be023b864b..de50a21603cc73 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/MethodBase.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/MethodBase.Mono.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace System.Reflection @@ -34,6 +35,7 @@ public partial class MethodBase return m; } + [RequiresUnreferencedCode("Metadata for the method might be incomplete or removed")] [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern MethodBase? GetCurrentMethod();