Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/project/list-of-diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL
| __`SYSLIB1060`__ | Specified marshaller type is invalid |
| __`SYSLIB1061`__ | Marshaller type has incompatible method signatures |
| __`SYSLIB1062`__ | Project must be updated with '\<AllowUnsafeBlocks\>true\</AllowUnsafeBlocks\>' |
| __`SYSLIB1063`__ | _`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._ |
| __`SYSLIB1064`__ | _`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._ |
| __`SYSLIB1063`__ | Unnecessary marshalling info |
| __`SYSLIB1064`__ | Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe' |
| __`SYSLIB1065`__ | _`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._ |
| __`SYSLIB1066`__ | _`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._ |
| __`SYSLIB1067`__ | _`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._ |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

namespace Microsoft.Interop
{
/// <summary>
/// Helpers for reasoning about the updated memory safety rules (unsafe evolution) in the interop generators.
/// </summary>
internal static class MemorySafetyRules
{
/// <summary>
/// The compiler feature flag that opts an assembly into the updated memory safety rules.
/// </summary>
/// <remarks>
/// Roslyn does not expose the memory safety rules version through a public API yet
/// (https://github.com/dotnet/roslyn/issues/82546), so we look at the same feature flag the compiler
/// itself uses to determine whether the updated rules are in effect.
/// </remarks>
private const string UpdatedMemorySafetyRulesFeature = "updated-memory-safety-rules";

/// <summary>
/// The <c>safe</c> contextual keyword introduced by the unsafe evolution feature.
/// </summary>
/// <remarks>
/// The generators compile against an older Roslyn than the one they run on, so the kind is resolved at
/// run time instead of referencing <c>SyntaxKind.SafeKeyword</c> directly. It is
/// <see cref="SyntaxKind.None"/> when the hosting compiler does not know the keyword.
/// </remarks>
private static readonly SyntaxKind s_safeKeyword = SyntaxFacts.GetContextualKeywordKind("safe");

/// <summary>
/// Determines whether the compilation the provided tree belongs to uses the updated memory safety rules.
/// </summary>
public static bool UsesUpdatedMemorySafetyRules(SyntaxTree tree)
=> tree.Options.Features.ContainsKey(UpdatedMemorySafetyRulesFeature);

/// <summary>
/// Determines whether a declaration explicitly states its safety contract with <c>safe</c> or <c>unsafe</c>.
/// </summary>
public static bool HasExplicitSafetyModifier(SyntaxTokenList modifiers)
=> modifiers.Any(SyntaxKind.UnsafeKeyword) || HasSafeModifier(modifiers);

/// <summary>
/// Determines whether a declaration is explicitly marked <c>safe</c>.
/// </summary>
public static bool HasSafeModifier(SyntaxTokenList modifiers)
=> s_safeKeyword != SyntaxKind.None && modifiers.Any(s_safeKeyword);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,15 @@
<data name="RequiresAllowUnsafeBlocksTitleLibraryImport" xml:space="preserve">
<value>LibraryImportAttribute requires unsafe code.</value>
</data>
<data name="RequiresExplicitSafetyModifierTitleLibraryImport" xml:space="preserve">
<value>Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</value>
</data>
<data name="RequiresExplicitSafetyModifierMessageLibraryImport" xml:space="preserve">
<value>Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</value>
</data>
<data name="RequiresExplicitSafetyModifierDescriptionLibraryImport" xml:space="preserve">
<value>Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</value>
</data>
<data name="RequiresAllowUnsafeBlocksTitleCom" xml:space="preserve">
<value>'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,21 @@
<target state="translated">LibraryImportAttribute vyžaduje nebezpečný kód.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierDescriptionLibraryImport">
<source>Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</source>
<target state="new">Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierMessageLibraryImport">
<source>Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierTitleLibraryImport">
<source>Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="ReturnTypeMustBeExpectedTypeDescription">
<source>The return type the two method must be the expected type.</source>
<target state="translated">Návratový typ, který obě metody musí být očekávaného typu.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,21 @@
<target state="translated">LibraryImportAttribute erfordert unsicheren Code.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierDescriptionLibraryImport">
<source>Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</source>
<target state="new">Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierMessageLibraryImport">
<source>Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierTitleLibraryImport">
<source>Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="ReturnTypeMustBeExpectedTypeDescription">
<source>The return type the two method must be the expected type.</source>
<target state="translated">Der Rückgabetyp, den die beiden Methoden aufweisen müssen, muss der erwartete Typ sein.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,21 @@
<target state="translated">LibraryImportAttribute requiere código no seguro.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierDescriptionLibraryImport">
<source>Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</source>
<target state="new">Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierMessageLibraryImport">
<source>Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierTitleLibraryImport">
<source>Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="ReturnTypeMustBeExpectedTypeDescription">
<source>The return type the two method must be the expected type.</source>
<target state="translated">El tipo de valor devuelto por el que ambos métodos deben ser del tipo esperado.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,21 @@
<target state="translated">LibraryImportAttribute requiert du code non sécurisé.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierDescriptionLibraryImport">
<source>Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</source>
<target state="new">Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierMessageLibraryImport">
<source>Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierTitleLibraryImport">
<source>Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="ReturnTypeMustBeExpectedTypeDescription">
<source>The return type the two method must be the expected type.</source>
<target state="translated">Le type de retour de la méthode deux doit être le type attendu.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,21 @@
<target state="translated">LibraryImportAttribute richiede un codice non sicuro.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierDescriptionLibraryImport">
<source>Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</source>
<target state="new">Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierMessageLibraryImport">
<source>Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierTitleLibraryImport">
<source>Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="ReturnTypeMustBeExpectedTypeDescription">
<source>The return type the two method must be the expected type.</source>
<target state="translated">Tipo restituito il due metodo deve essere il tipo previsto.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,21 @@
<target state="translated">LibraryImportAttribute には安全でないコードが必要です。</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierDescriptionLibraryImport">
<source>Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</source>
<target state="new">Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierMessageLibraryImport">
<source>Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierTitleLibraryImport">
<source>Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="ReturnTypeMustBeExpectedTypeDescription">
<source>The return type the two method must be the expected type.</source>
<target state="translated">戻り値の型は、2 つのメソッドが期待する型である必要があります。</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,21 @@
<target state="translated">LibraryImportAttribute에는 안전하지 않은 코드가 필요합니다.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierDescriptionLibraryImport">
<source>Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</source>
<target state="new">Under the updated memory safety rules, calling into native code is a safety contract that the compiler cannot verify. Mark the method 'unsafe' to require callers to audit the call, or 'safe' after auditing the interop boundary. The generated implementation may or may not be 'extern' depending on the marshalling that is required, so the modifier is required for every method with 'LibraryImportAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierMessageLibraryImport">
<source>Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method '{0}' with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="RequiresExplicitSafetyModifierTitleLibraryImport">
<source>Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</source>
<target state="new">Method with 'LibraryImportAttribute' must be marked 'safe' or 'unsafe'</target>
<note />
</trans-unit>
<trans-unit id="ReturnTypeMustBeExpectedTypeDescription">
<source>The return type the two method must be the expected type.</source>
<target state="translated">두 메서드가 필요한 형식이어야 하는 반환 형식입니다.</target>
Expand Down
Loading
Loading