From 06352f8c95966e0ce2e088181d04dc40ebb55cc8 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 11 Jul 2023 14:38:26 -0700 Subject: [PATCH 1/8] SizeConst is required by all runtimes for UnmanagedType.ByValArray, so require it when decoding instead of defaulting to length 1. --- .../Symbols/Attributes/MarshalAsAttributeDecoder.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs b/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs index a688950774c1d..17370d9bbd08d 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs @@ -209,7 +209,7 @@ private static void DecodeMarshalAsArray(ref DecodeWellKnownAttributeArguments().GetOrCreateData(); From ac60b588b07eb6582cc3770da97253478e50aae6 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 11 Jul 2023 14:56:55 -0700 Subject: [PATCH 2/8] Update tests --- .../Emit2/Attributes/AttributeTests_MarshalAs.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs b/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs index 376cdcb700292..160e027dbbee2 100644 --- a/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs +++ b/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs @@ -570,10 +570,10 @@ public void NativeTypeFixedArray() public class X { - [MarshalAs(UnmanagedType.ByValArray)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public int ByValArray0; - [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.ByValTStr, IidParameterIndex = -1, MarshalCookie = null, MarshalType = null, MarshalTypeRef = null, + [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.ByValTStr, IidParameterIndex = -1, SizeConst = 1, MarshalCookie = null, MarshalType = null, MarshalTypeRef = null, SafeArrayUserDefinedSubType = null)] public int ByValArray1; @@ -585,10 +585,10 @@ public class X MarshalCookie = null, MarshalType = null, MarshalTypeRef = null, SafeArrayUserDefinedSubType = null)] public int ByValArray3; - [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AsAny)] + [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AsAny, SizeConst = 1)] public int ByValArray4; - [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.CustomMarshaler)] + [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.CustomMarshaler, SizeConst = 1)] public int ByValArray5; } "; @@ -656,9 +656,15 @@ public class X // (8,170): error CS7045: Parameter not valid for the specified unmanaged type. // [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.ByValTStr, SafeArraySubType = VarEnum.VT_BSTR, SafeArrayUserDefinedSubType = null, SizeConst = -1, SizeParamIndex = -1)]int ByValArray_e1; Diagnostic(ErrorCode.ERR_ParameterNotValidForType, "SizeParamIndex = -1"), + // (9,6): error CS7046: Attribute parameter 'SizeConst' must be specified. + // [MarshalAs(UnmanagedType.ByValArray, SizeParamIndex = short.MaxValue)] int ByValArray_e2; + Diagnostic(ErrorCode.ERR_AttributeParameterRequired1, "MarshalAs").WithArguments("SizeConst"), // (9,42): error CS7045: Parameter not valid for the specified unmanaged type. // [MarshalAs(UnmanagedType.ByValArray, SizeParamIndex = short.MaxValue)] int ByValArray_e2; Diagnostic(ErrorCode.ERR_ParameterNotValidForType, "SizeParamIndex = short.MaxValue"), + // (10,6): error CS7046: Attribute parameter 'SizeConst' must be specified. + // [MarshalAs(UnmanagedType.ByValArray, SafeArraySubType = VarEnum.VT_I2)] int ByValArray_e3; + Diagnostic(ErrorCode.ERR_AttributeParameterRequired1, "MarshalAs").WithArguments("SizeConst"), // (10,42): error CS7045: Parameter not valid for the specified unmanaged type. // [MarshalAs(UnmanagedType.ByValArray, SafeArraySubType = VarEnum.VT_I2)] int ByValArray_e3; Diagnostic(ErrorCode.ERR_ParameterNotValidForType, "SafeArraySubType = VarEnum.VT_I2"), From 89322ae770b086d24b78682e13f5210ac53a7eb9 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 12 Jul 2023 10:56:18 -0700 Subject: [PATCH 3/8] Try to emit the diagnostic as a warning-wave warning. --- src/Compilers/CSharp/Portable/CSharpResources.resx | 6 ++++++ src/Compilers/CSharp/Portable/Errors/ErrorCode.cs | 1 + src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs | 1 + .../CSharp/Portable/Errors/MessageProvider.cs | 2 ++ .../CSharp/Portable/Generated/ErrorFacts.Generated.cs | 1 + .../CSharp/Portable/xlf/CSharpResources.cs.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.de.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.es.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.fr.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.it.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.ja.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.ko.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.pl.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.pt-BR.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.ru.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.tr.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf | 10 ++++++++++ .../Test/Emit2/Attributes/AttributeTests_MarshalAs.cs | 8 ++++---- .../Core/Portable/Diagnostic/CommonMessageProvider.cs | 2 ++ .../Symbols/Attributes/MarshalAsAttributeDecoder.cs | 10 +++++++--- src/Compilers/Test/Core/Mocks/TestMessageProvider.cs | 2 ++ .../VisualBasic/Portable/Errors/MessageProvider.vb | 6 ++++++ 23 files changed, 162 insertions(+), 7 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index a56bc754cf0eb..02915cf962bcb 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -7499,6 +7499,12 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ The '&' operator should not be used on parameters or local variables in async methods. + + Attribute parameter 'SizeConst' must be specified. + + + Attribute parameter 'SizeConst' must be specified. + 'static' modifier must precede 'unsafe' modifier. diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index ca89dd2af9635..992072fd0d4e5 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -2182,6 +2182,7 @@ internal enum ErrorCode ERR_StructLayoutCyclePrimaryConstructorParameter = 9121, ERR_UnexpectedParameterList = 9122, WRN_AddressOfInAsync = 9123, + WRN_ByValArraySizeConstRequired = 9124, ERR_BadRefInUsingAlias = 9130, ERR_BadUnsafeInUsingDirective = 9131, diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs index beaf7cfeab2db..8249cb9919e20 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs @@ -207,6 +207,7 @@ internal static int GetWarningLevel(ErrorCode code) switch (code) { case ErrorCode.WRN_AddressOfInAsync: + case ErrorCode.WRN_ByValArraySizeConstRequired: // Warning level 8 is exclusively for warnings introduced in the compiler // shipped with dotnet 8 (C# 12) and that can be reported for pre-existing code. return 8; diff --git a/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs b/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs index 887eb2aa5e307..6bab97e4ba5fc 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs @@ -309,5 +309,7 @@ protected override void ReportAttributeParameterRequired(DiagnosticBag diagnosti } public override int ERR_BadAssemblyName => (int)ErrorCode.ERR_BadAssemblyName; + + public override int WRN_ByValArraySizeConstRequired => (int)ErrorCode.WRN_ByValArraySizeConstRequired; } } diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs index c1203a2275310..803c6cbf44e89 100644 --- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs @@ -315,6 +315,7 @@ public static bool IsWarning(ErrorCode code) case ErrorCode.WRN_CapturedPrimaryConstructorParameterPassedToBase: case ErrorCode.WRN_UnreadPrimaryConstructorParameter: case ErrorCode.WRN_AddressOfInAsync: + case ErrorCode.WRN_ByValArraySizeConstRequired: return true; default: return false; diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 588f6291a16a7..08c9a4cf89233 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -2077,6 +2077,16 @@ Typ nelze v tomto kontextu použít, protože se nedá reprezentovat v metadatech. + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope Tato kombinace argumentů parametru {0} může vystavit proměnné, na které odkazuje parametr {1}, mimo obor jejich deklarace diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index fe193068e7b22..f4b0359a0f7dc 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -2077,6 +2077,16 @@ Der Typ kann in diesem Kontext nicht verwendet werden, da er nicht in den Metadaten dargestellt werden kann. + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope Diese Kombination aus Argumenten für "{0}" führt möglicherweise dazu, dass vom Parameter "{1}" referenzierte Variablen außerhalb ihres Deklarationsbereichs verfügbar gemacht werden. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index 74aafa9bdae23..30d14d6cc9aa1 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -2077,6 +2077,16 @@ El tipo no se puede usar en este contexto porque no se puede representar en metadatos. + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope Esta combinación de argumentos para "{0}" puede exponer variables a las que el parámetro "{1}" hace referencia fuera de su ámbito de declaración diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index bfa963a4909ca..bd86fb0ed5a5e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -2077,6 +2077,16 @@ Le type ne peut pas être utilisé dans ce contexte, car il ne peut pas être représenté dans les métadonnées. + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope Cette combinaison d'arguments pour '{0}' peut exposer les variables référencées par le paramètre '{1}' en dehors de la portée de leur déclaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 87b1b848b98aa..d3a3a94238e44 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -2077,6 +2077,16 @@ Non è possibile usare il tipo in questo contesto perché non può essere rappresentato nei metadati. + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope Questa combinazione di argomenti per '{0}' può esporre variabili a cui fa riferimento il parametro '{1}' all'esterno del relativo ambito di dichiarazione diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 7d0fcb6a899a2..0b6dc953842cb 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -2077,6 +2077,16 @@ 型は、メタデータで表現できないため、このコンテキストで使用することはできません。 + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope '{0}' に対するこの引数の組み合わせは、パラメーター '{1}' によって参照される変数が宣言のスコープ外に公開される可能性があります diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index d0433fb342b77..4d32969e84c36 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -2077,6 +2077,16 @@ 유형은 메타데이터로 표현할 수 없기 때문에 이 컨텍스트에서 사용할 수 없습니다. + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope '{0}'에 대한 이 인수 조합은 선언 범위 외부에 있는 '{1}' 매개 변수에서 참조하는 변수를 노출할 수 있습니다. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 9dba88b5adf95..bfb794164afec 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -2077,6 +2077,16 @@ Typ nie może być używany w tym kontekście, ponieważ nie może być reprezentowany w metadanych. + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope Ta kombinacja argumentów „{0}” może uwidaczniać zmienne przywoływane przez parametr „{1}” poza zakresem deklaracji diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 503a69a7a0ba5..a332b423800b8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -2077,6 +2077,16 @@ O tipo não pode ser usado neste contexto porque ele não pode ser representado em metadados. + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope Essa combinação de argumentos para '{0}' pode expor variáveis referenciadas pelo parâmetro '{1}' fora de seu escopo de declaração diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 5bd7dbc9112c4..80536005ad81f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -2077,6 +2077,16 @@ Невозможно использовать тип в этом контексте, поскольку он не может быть представлен в метаданных. + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope Это сочетание аргументов для "{0}" может представить переменные, на которые ссылается параметр "{1}", за пределами их области объявления diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 62152e7ec4517..a30cc5aeb1683 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -2077,6 +2077,16 @@ Tür meta verilerde temsili olmadığından bu bağlamda kullanılamaz. + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope '{0}' argümanlarının bu kombinasyonu, '{1}' parametresi tarafından başvurulan değişkenleri bildirim kapsamının dışında gösterebilir. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 7d215d637d732..be5f69194b7b8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -2077,6 +2077,16 @@ 类型不能在此上下文中使用,因为它不能在元数据中表示。 + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope “{0}”的这种参数组合可能会在变量声明范围之外公开由参数“{1}”引用的变量 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 61871d380626e..8289d5c09fef8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -2077,6 +2077,16 @@ 無法在此內容中使用類型,因為它無法在中繼資料中表示。 + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + + + Attribute parameter 'SizeConst' must be specified. + Attribute parameter 'SizeConst' must be specified. + + This combination of arguments to '{0}' may expose variables referenced by parameter '{1}' outside of their declaration scope 對 '{0}' 使用此引數組合,會在其宣告範圍外公開參數 '{1}' 所參考的變數 diff --git a/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs b/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs index 160e027dbbee2..ebbed4bd491e9 100644 --- a/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs +++ b/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs @@ -656,15 +656,15 @@ public class X // (8,170): error CS7045: Parameter not valid for the specified unmanaged type. // [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.ByValTStr, SafeArraySubType = VarEnum.VT_BSTR, SafeArrayUserDefinedSubType = null, SizeConst = -1, SizeParamIndex = -1)]int ByValArray_e1; Diagnostic(ErrorCode.ERR_ParameterNotValidForType, "SizeParamIndex = -1"), - // (9,6): error CS7046: Attribute parameter 'SizeConst' must be specified. + // (9,6): warning CS9124: Attribute parameter 'SizeConst' must be specified. // [MarshalAs(UnmanagedType.ByValArray, SizeParamIndex = short.MaxValue)] int ByValArray_e2; - Diagnostic(ErrorCode.ERR_AttributeParameterRequired1, "MarshalAs").WithArguments("SizeConst"), + Diagnostic(ErrorCode.WRN_ByValArraySizeConstRequired, "MarshalAs(UnmanagedType.ByValArray, SizeParamIndex = short.MaxValue)"), // (9,42): error CS7045: Parameter not valid for the specified unmanaged type. // [MarshalAs(UnmanagedType.ByValArray, SizeParamIndex = short.MaxValue)] int ByValArray_e2; Diagnostic(ErrorCode.ERR_ParameterNotValidForType, "SizeParamIndex = short.MaxValue"), - // (10,6): error CS7046: Attribute parameter 'SizeConst' must be specified. + // (10,6): warning CS9124: Attribute parameter 'SizeConst' must be specified. // [MarshalAs(UnmanagedType.ByValArray, SafeArraySubType = VarEnum.VT_I2)] int ByValArray_e3; - Diagnostic(ErrorCode.ERR_AttributeParameterRequired1, "MarshalAs").WithArguments("SizeConst"), + Diagnostic(ErrorCode.WRN_ByValArraySizeConstRequired, "MarshalAs(UnmanagedType.ByValArray, SafeArraySubType = VarEnum.VT_I2)"), // (10,42): error CS7045: Parameter not valid for the specified unmanaged type. // [MarshalAs(UnmanagedType.ByValArray, SafeArraySubType = VarEnum.VT_I2)] int ByValArray_e3; Diagnostic(ErrorCode.ERR_ParameterNotValidForType, "SafeArraySubType = VarEnum.VT_I2"), diff --git a/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs b/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs index 3b52ae4be55ac..c24590d435e23 100644 --- a/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs +++ b/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs @@ -328,5 +328,7 @@ public void ReportAttributeParameterRequired(BindingDiagnosticBag diagnostics, S } public abstract int ERR_BadAssemblyName { get; } + + public abstract int WRN_ByValArraySizeConstRequired { get; } } } diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs b/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs index 17370d9bbd08d..bca46ed674460 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs @@ -272,9 +272,13 @@ private static void DecodeMarshalAsArray(ref DecodeWellKnownAttributeArguments 0) + { + arguments.Diagnostics.Add(messageProvider.CreateDiagnostic(messageProvider.WRN_ByValArraySizeConstRequired, arguments.AttributeSyntaxOpt.GetLocation())); + } + elementCount = 1; } } diff --git a/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs b/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs index 0cfc4e48dd9c2..d943f0d055764 100644 --- a/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs +++ b/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs @@ -469,5 +469,7 @@ public override int ERR_InvalidDebugInfo public override int WRN_DuplicateAnalyzerReference => throw new NotImplementedException(); public override int ERR_FunctionPointerTypesInAttributeNotSupported => throw new NotImplementedException(); + + public override int WRN_ByValArraySizeConstRequired => throw new NotImplementedException(); } } diff --git a/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb b/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb index 7919e4a630573..7730bb87c70d6 100644 --- a/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb +++ b/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb @@ -622,6 +622,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End Get End Property + Public Overrides ReadOnly Property WRN_ByValArraySizeConstRequired As Integer + Get + Return ERRID.Unknown + End Get + End Property + End Class End Namespace From d5584818010135f6af2ac69696da5a6c8a6b908d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 12 Jul 2023 15:54:34 -0700 Subject: [PATCH 4/8] Add case to IsBuildOnlyDiagnostic --- src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs index bf64f872f7b98..2691a298fd2ce 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs @@ -2361,6 +2361,7 @@ internal static bool IsBuildOnlyDiagnostic(ErrorCode code) case ErrorCode.ERR_CollectionLiteralTargetTypeNotConstructible: case ErrorCode.ERR_ExpressionTreeContainsCollectionLiteral: case ErrorCode.ERR_CollectionLiteralNoTargetType: + case ErrorCode.WRN_ByValArraySizeConstRequired: return false; default: // NOTE: All error codes must be explicitly handled in this switch statement From 900a32790dcfb76d196b42b955203ea2eda71701 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 13 Jul 2023 12:03:29 -0700 Subject: [PATCH 5/8] Add case for new diagnostic. --- src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs index 0ff106b79fbfb..44824533778b7 100644 --- a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs +++ b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs @@ -445,6 +445,7 @@ public void WarningLevel_2() Assert.Equal(7, ErrorFacts.GetWarningLevel(errorCode)); break; case ErrorCode.WRN_AddressOfInAsync: + case ErrorCode.WRN_ByValArraySizeConstRequired: // These are the warnings introduced with the warning "wave" shipped with dotnet 8 and C# 12. Assert.Equal(8, ErrorFacts.GetWarningLevel(errorCode)); break; From cdaaacffac02894eab1b65ebc4e35f6ebd9b60a5 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 13 Jul 2023 14:51:16 -0700 Subject: [PATCH 6/8] Regenerate files --- src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs index 955d523ee872a..612e07528ad04 100644 --- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs @@ -316,10 +316,10 @@ public static bool IsWarning(ErrorCode code) case ErrorCode.WRN_UnreadPrimaryConstructorParameter: case ErrorCode.WRN_AddressOfInAsync: case ErrorCode.WRN_CapturedPrimaryConstructorParameterInFieldInitializer: + case ErrorCode.WRN_ByValArraySizeConstRequired: case ErrorCode.WRN_InterceptorSignatureMismatch: case ErrorCode.WRN_NullabilityMismatchInReturnTypeOnInterceptor: case ErrorCode.WRN_NullabilityMismatchInParameterTypeOnInterceptor: - case ErrorCode.WRN_ByValArraySizeConstRequired: return true; default: return false; From 5f95199ca7b7191d294ce8e03b5c1403aaece283 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 14 Jul 2023 14:27:55 -0700 Subject: [PATCH 7/8] Change to using nullable int instead of unknown error id --- src/Compilers/CSharp/Portable/Errors/MessageProvider.cs | 2 +- .../Core/Portable/Diagnostic/CommonMessageProvider.cs | 2 +- .../Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs | 4 ++-- src/Compilers/Test/Core/Mocks/TestMessageProvider.cs | 2 +- src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs b/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs index 6bab97e4ba5fc..51b5bf8f104cd 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs @@ -310,6 +310,6 @@ protected override void ReportAttributeParameterRequired(DiagnosticBag diagnosti public override int ERR_BadAssemblyName => (int)ErrorCode.ERR_BadAssemblyName; - public override int WRN_ByValArraySizeConstRequired => (int)ErrorCode.WRN_ByValArraySizeConstRequired; + public override int? WRN_ByValArraySizeConstRequired => (int)ErrorCode.WRN_ByValArraySizeConstRequired; } } diff --git a/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs b/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs index c24590d435e23..afca96c5e1e44 100644 --- a/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs +++ b/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs @@ -329,6 +329,6 @@ public void ReportAttributeParameterRequired(BindingDiagnosticBag diagnostics, S public abstract int ERR_BadAssemblyName { get; } - public abstract int WRN_ByValArraySizeConstRequired { get; } + public abstract int? WRN_ByValArraySizeConstRequired { get; } } } diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs b/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs index bca46ed674460..9f142dde0e428 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs @@ -274,9 +274,9 @@ private static void DecodeMarshalAsArray(ref DecodeWellKnownAttributeArguments 0) + if (messageProvider.WRN_ByValArraySizeConstRequired is { } warningCode) { - arguments.Diagnostics.Add(messageProvider.CreateDiagnostic(messageProvider.WRN_ByValArraySizeConstRequired, arguments.AttributeSyntaxOpt.GetLocation())); + arguments.Diagnostics.Add(messageProvider.CreateDiagnostic(warningCode, arguments.AttributeSyntaxOpt.GetLocation())); } elementCount = 1; } diff --git a/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs b/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs index d943f0d055764..68c2c5c6b9937 100644 --- a/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs +++ b/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs @@ -470,6 +470,6 @@ public override int ERR_InvalidDebugInfo public override int ERR_FunctionPointerTypesInAttributeNotSupported => throw new NotImplementedException(); - public override int WRN_ByValArraySizeConstRequired => throw new NotImplementedException(); + public override int? WRN_ByValArraySizeConstRequired => throw new NotImplementedException(); } } diff --git a/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb b/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb index 7730bb87c70d6..56e89b59d525e 100644 --- a/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb +++ b/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb @@ -622,9 +622,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End Get End Property - Public Overrides ReadOnly Property WRN_ByValArraySizeConstRequired As Integer + Public Overrides ReadOnly Property WRN_ByValArraySizeConstRequired As Integer? Get - Return ERRID.Unknown + Return Nothing End Get End Property From 80ca43636705ffce373a6872dcf75bb33beb1c4b Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 25 Jul 2023 16:19:33 -0700 Subject: [PATCH 8/8] PR feedback --- .../Attributes/AttributeTests_MarshalAs.cs | 50 +++++++++++++++++-- .../Attributes/MarshalAsAttributeDecoder.cs | 15 +++--- .../Attributes/AttributeTests_MarshalAs.vb | 1 + 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs b/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs index ebbed4bd491e9..ff16016296591 100644 --- a/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs +++ b/src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_MarshalAs.cs @@ -565,15 +565,14 @@ class X public void NativeTypeFixedArray() { var source = @" -using System; using System.Runtime.InteropServices; public class X { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + [MarshalAs(UnmanagedType.ByValArray)] public int ByValArray0; - [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.ByValTStr, IidParameterIndex = -1, SizeConst = 1, MarshalCookie = null, MarshalType = null, MarshalTypeRef = null, + [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.ByValTStr, IidParameterIndex = -1, MarshalCookie = null, MarshalType = null, MarshalTypeRef = null, SafeArrayUserDefinedSubType = null)] public int ByValArray1; @@ -585,10 +584,10 @@ public class X MarshalCookie = null, MarshalType = null, MarshalTypeRef = null, SafeArrayUserDefinedSubType = null)] public int ByValArray3; - [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AsAny, SizeConst = 1)] + [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AsAny)] public int ByValArray4; - [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.CustomMarshaler, SizeConst = 1)] + [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.CustomMarshaler)] public int ByValArray5; } "; @@ -603,6 +602,20 @@ public class X }; var verifier = CompileAndVerifyFieldMarshal(source, blobs); + verifier.VerifyDiagnostics( + // (6,6): warning CS9125: Attribute parameter 'SizeConst' must be specified. + // [MarshalAs(UnmanagedType.ByValArray)] + Diagnostic(ErrorCode.WRN_ByValArraySizeConstRequired, "MarshalAs(UnmanagedType.ByValArray)").WithLocation(6, 6), + // (9,6): warning CS9125: Attribute parameter 'SizeConst' must be specified. + // [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.ByValTStr, IidParameterIndex = -1, MarshalCookie = null, MarshalType = null, MarshalTypeRef = null, + Diagnostic(ErrorCode.WRN_ByValArraySizeConstRequired, @"MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.ByValTStr, IidParameterIndex = -1, MarshalCookie = null, MarshalType = null, MarshalTypeRef = null, + SafeArrayUserDefinedSubType = null)").WithLocation(9, 6), + // (21,6): warning CS9125: Attribute parameter 'SizeConst' must be specified. + // [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AsAny)] + Diagnostic(ErrorCode.WRN_ByValArraySizeConstRequired, "MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AsAny)").WithLocation(21, 6), + // (24,6): warning CS9125: Attribute parameter 'SizeConst' must be specified. + // [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.CustomMarshaler)] + Diagnostic(ErrorCode.WRN_ByValArraySizeConstRequired, "MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.CustomMarshaler)").WithLocation(24, 6)); VerifyFieldMetadataDecoding(verifier, blobs); } @@ -673,6 +686,33 @@ public class X Diagnostic(ErrorCode.ERR_InvalidNamedArgument, "SizeConst = 0x20000000").WithArguments("SizeConst")); } + [Fact] + [WorkItem(68988, "https://github.com/dotnet/roslyn/issues/68988")] + public void NativeTypeFixedArray_SizeConstWarning_RespectsWarningLevel() + { + var source = @" +using System.Runtime.InteropServices; + +public class X +{ + [MarshalAs(UnmanagedType.ByValArray)] + public int ByValArray0; +} +"; + CreateCompilation( + source, + options: TestOptions.ReleaseDll.WithWarningLevel(7)) + .VerifyDiagnostics(); + + CreateCompilation( + source, + options: TestOptions.ReleaseDll.WithWarningLevel(8)) + .VerifyDiagnostics( + // (6,6): warning CS9125: Attribute parameter 'SizeConst' must be specified. + // [MarshalAs(UnmanagedType.ByValArray)] + Diagnostic(ErrorCode.WRN_ByValArraySizeConstRequired, "MarshalAs(UnmanagedType.ByValArray)").WithLocation(6, 6)); + } + /// /// (SafeArraySubType, SafeArrayUserDefinedSubType), (ArraySubType, SizeConst, SizeParamIndex) not allowed, /// (SafeArraySubType, SafeArrayUserDefinedSubType) not allowed together unless VT_DISPATCH, VT_UNKNOWN, VT_RECORD; others ignored. diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs b/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs index 9f142dde0e428..8613c4a0ddbdc 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/MarshalAsAttributeDecoder.cs @@ -268,18 +268,15 @@ private static void DecodeMarshalAsArray(ref DecodeWellKnownAttributeArguments