Skip to content

Commit 45e1e2c

Browse files
authored
Add diagnostic when the size of an array that is marshalled to the callee is an 'out' parameter. (#89827)
1 parent 23ce050 commit 45e1e2c

File tree

22 files changed

+524
-6
lines changed

22 files changed

+524
-6
lines changed

src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,20 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M
310310
})
311311
};
312312
}
313+
var direction = GetDirectionFromOptions(generatedComInterfaceAttributeData.Options);
314+
315+
// Ensure the size of collections are known at marshal / unmarshal in time.
316+
// A collection that is marshalled in cannot have a size that is an 'out' parameter.
317+
foreach (TypePositionInfo parameter in signatureContext.ManagedParameters)
318+
{
319+
MarshallerHelpers.ValidateCountInfoAvailableAtCall(
320+
direction,
321+
parameter,
322+
generatorDiagnostics,
323+
symbol,
324+
GeneratorDiagnostics.SizeOfInCollectionMustBeDefinedAtCallOutParam,
325+
GeneratorDiagnostics.SizeOfInCollectionMustBeDefinedAtCallReturnValue);
326+
}
313327

314328
var containingSyntaxContext = new ContainingSyntaxContext(syntax);
315329

@@ -322,7 +336,7 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M
322336

323337
var declaringType = ManagedTypeInfo.CreateTypeInfoForTypeSymbol(symbol.ContainingType);
324338

325-
var virtualMethodIndexData = new VirtualMethodIndexData(index, ImplicitThisParameter: true, GetDirectionFromOptions(generatedComInterfaceAttributeData.Options), true, ExceptionMarshalling.Com);
339+
var virtualMethodIndexData = new VirtualMethodIndexData(index, ImplicitThisParameter: true, direction, true, ExceptionMarshalling.Com);
326340

327341
return new IncrementalMethodStubGenerationContext(
328342
signatureContext,

src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratorDiagnostics.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,26 @@ public class Ids
444444
WellKnownDiagnosticTags.Unnecessary
445445
});
446446

447+
/// <inheritdoc cref="SR.SizeOfCollectionMustBeKnownAtMarshalTimeMessageOutParam"/>
448+
public static readonly DiagnosticDescriptor SizeOfInCollectionMustBeDefinedAtCallOutParam =
449+
new DiagnosticDescriptor(
450+
Ids.InvalidGeneratedComInterfaceAttributeUsage,
451+
GetResourceString(nameof(SR.SizeOfCollectionMustBeKnownAtMarshalTimeTitle)),
452+
GetResourceString(nameof(SR.SizeOfCollectionMustBeKnownAtMarshalTimeMessageOutParam)),
453+
Category,
454+
DiagnosticSeverity.Warning,
455+
isEnabledByDefault: true);
456+
457+
/// <inheritdoc cref="SR.SizeOfCollectionMustBeKnownAtMarshalTimeMessageReturnValue"/>
458+
public static readonly DiagnosticDescriptor SizeOfInCollectionMustBeDefinedAtCallReturnValue =
459+
new DiagnosticDescriptor(
460+
Ids.InvalidGeneratedComInterfaceAttributeUsage,
461+
GetResourceString(nameof(SR.SizeOfCollectionMustBeKnownAtMarshalTimeTitle)),
462+
GetResourceString(nameof(SR.SizeOfCollectionMustBeKnownAtMarshalTimeMessageReturnValue)),
463+
Category,
464+
DiagnosticSeverity.Warning,
465+
isEnabledByDefault: true);
466+
447467
/// <inheritdoc cref="SR.ComMethodReturningIntWillBeOutParameterMessage"/>
448468
public static readonly DiagnosticDescriptor ComMethodManagedReturnWillBeOutVariable =
449469
new DiagnosticDescriptor(

src/libraries/System.Runtime.InteropServices/gen/Common/Resources/Strings.resx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,15 @@
700700
<data name="RuntimeComApisDoNotSupportSourceGeneratedComTitle" xml:space="preserve">
701701
<value>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM</value>
702702
</data>
703+
<data name="SizeOfCollectionMustBeKnownAtMarshalTimeTitle" xml:space="preserve">
704+
<value>The size of a collection that is marshalled to the callee must be defined when the method is called.</value>
705+
</data>
706+
<data name="SizeOfCollectionMustBeKnownAtMarshalTimeMessageOutParam" xml:space="preserve">
707+
<value>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</value>
708+
</data>
709+
<data name="SizeOfCollectionMustBeKnownAtMarshalTimeMessageReturnValue" xml:space="preserve">
710+
<value>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</value>
711+
</data>
703712
<data name="StatefulMarshallerRequiresFreeDescription" xml:space="preserve">
704713
<value>A stateful marshaller must have a zero-parameter void-returning instance method named 'Free'.</value>
705714
</data>

src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,21 @@
997997
<target state="translated">Abstraktní typ odvozený ze SafeHandle nelze zařadit pomocí odkazu. Poskytnutý typ musí být konkrétní.</target>
998998
<note />
999999
</trans-unit>
1000+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageOutParam">
1001+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</source>
1002+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</target>
1003+
<note />
1004+
</trans-unit>
1005+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageReturnValue">
1006+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</source>
1007+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</target>
1008+
<note />
1009+
</trans-unit>
1010+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeTitle">
1011+
<source>The size of a collection that is marshalled to the callee must be defined when the method is called.</source>
1012+
<target state="new">The size of a collection that is marshalled to the callee must be defined when the method is called.</target>
1013+
<note />
1014+
</trans-unit>
10001015
<trans-unit id="StatefulMarshallerRequiresFreeDescription">
10011016
<source>A stateful marshaller must have a zero-parameter void-returning instance method named 'Free'.</source>
10021017
<target state="translated">Stavový zařazovač musí mít instanční metodu s názvem Free, která nemá žádné parametry a vrací void.</target>

src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,21 @@
997997
<target state="translated">Ein abstrakter Typ, der von \"SafeHandle\" abgeleitet wird, kann nicht als Verweis gemarshallt werden. Der angegebene Typ muss ein konkretes Element sein.</target>
998998
<note />
999999
</trans-unit>
1000+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageOutParam">
1001+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</source>
1002+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</target>
1003+
<note />
1004+
</trans-unit>
1005+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageReturnValue">
1006+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</source>
1007+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</target>
1008+
<note />
1009+
</trans-unit>
1010+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeTitle">
1011+
<source>The size of a collection that is marshalled to the callee must be defined when the method is called.</source>
1012+
<target state="new">The size of a collection that is marshalled to the callee must be defined when the method is called.</target>
1013+
<note />
1014+
</trans-unit>
10001015
<trans-unit id="StatefulMarshallerRequiresFreeDescription">
10011016
<source>A stateful marshaller must have a zero-parameter void-returning instance method named 'Free'.</source>
10021017
<target state="translated">Ein statusbehafteter Marshaller muss eine Instanzmethode mit dem Namen „Free“ mit null Parametern haben, die „nichtig“ zurückgibt.</target>

src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,21 @@
997997
<target state="translated">Un tipo abstracto derivado de “SafeHandle” no se puede serializar por referencia. El tipo proporcionado debe ser concreto.</target>
998998
<note />
999999
</trans-unit>
1000+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageOutParam">
1001+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</source>
1002+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</target>
1003+
<note />
1004+
</trans-unit>
1005+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageReturnValue">
1006+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</source>
1007+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</target>
1008+
<note />
1009+
</trans-unit>
1010+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeTitle">
1011+
<source>The size of a collection that is marshalled to the callee must be defined when the method is called.</source>
1012+
<target state="new">The size of a collection that is marshalled to the callee must be defined when the method is called.</target>
1013+
<note />
1014+
</trans-unit>
10001015
<trans-unit id="StatefulMarshallerRequiresFreeDescription">
10011016
<source>A stateful marshaller must have a zero-parameter void-returning instance method named 'Free'.</source>
10021017
<target state="translated">Un serializador con estado debe tener un método de instancia de devolución void de parámetro cero denominado 'Free'.</target>

src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,21 @@
997997
<target state="translated">Un type abstrait dérivé de « SafeHandle » ne peut pas être marshalé par référence. Le type fourni doit être concret.</target>
998998
<note />
999999
</trans-unit>
1000+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageOutParam">
1001+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</source>
1002+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</target>
1003+
<note />
1004+
</trans-unit>
1005+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageReturnValue">
1006+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</source>
1007+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</target>
1008+
<note />
1009+
</trans-unit>
1010+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeTitle">
1011+
<source>The size of a collection that is marshalled to the callee must be defined when the method is called.</source>
1012+
<target state="new">The size of a collection that is marshalled to the callee must be defined when the method is called.</target>
1013+
<note />
1014+
</trans-unit>
10001015
<trans-unit id="StatefulMarshallerRequiresFreeDescription">
10011016
<source>A stateful marshaller must have a zero-parameter void-returning instance method named 'Free'.</source>
10021017
<target state="translated">Un marshaleur avec état doit avoir une méthode d’instance de retour void de paramètre zéro nommée 'Free'.</target>

src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,21 @@
997997
<target state="translated">Non è possibile effettuare il marshalling per riferimento di un tipo astratto derivato da 'SafeHandle'. Il tipo specificato deve essere concreto.</target>
998998
<note />
999999
</trans-unit>
1000+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageOutParam">
1001+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</source>
1002+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</target>
1003+
<note />
1004+
</trans-unit>
1005+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageReturnValue">
1006+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</source>
1007+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</target>
1008+
<note />
1009+
</trans-unit>
1010+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeTitle">
1011+
<source>The size of a collection that is marshalled to the callee must be defined when the method is called.</source>
1012+
<target state="new">The size of a collection that is marshalled to the callee must be defined when the method is called.</target>
1013+
<note />
1014+
</trans-unit>
10001015
<trans-unit id="StatefulMarshallerRequiresFreeDescription">
10011016
<source>A stateful marshaller must have a zero-parameter void-returning instance method named 'Free'.</source>
10021017
<target state="translated">Un gestore di marshalling con stato deve avere un metodo di istanza con restituzione void con parametro zero denominato 'Free'.</target>

src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,21 @@
997997
<target state="translated">'SafeHandle' から派生した抽象型は、参照でマーシャリングできません。指定される型は具象型である必要があります。</target>
998998
<note />
999999
</trans-unit>
1000+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageOutParam">
1001+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</source>
1002+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</target>
1003+
<note />
1004+
</trans-unit>
1005+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageReturnValue">
1006+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</source>
1007+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</target>
1008+
<note />
1009+
</trans-unit>
1010+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeTitle">
1011+
<source>The size of a collection that is marshalled to the callee must be defined when the method is called.</source>
1012+
<target state="new">The size of a collection that is marshalled to the callee must be defined when the method is called.</target>
1013+
<note />
1014+
</trans-unit>
10001015
<trans-unit id="StatefulMarshallerRequiresFreeDescription">
10011016
<source>A stateful marshaller must have a zero-parameter void-returning instance method named 'Free'.</source>
10021017
<target state="translated">ステートフル マーシャラーには、'Free' という名前で、パラメーターがなく、‘void’ を返すインスタンス メソッドが必要です。</target>

src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,21 @@
997997
<target state="translated">'SafeHandle'에서 파생된 추상 형식은 참조로 마샬링할 수 없습니다. 제공된 형식은 구체적이어야 합니다.</target>
998998
<note />
999999
</trans-unit>
1000+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageOutParam">
1001+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</source>
1002+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but count parameter '{1}' is an 'out' parameter.</target>
1003+
<note />
1004+
</trans-unit>
1005+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeMessageReturnValue">
1006+
<source>The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</source>
1007+
<target state="new">The size of parameter '{0}' that is marshalled to the callee must be defined when the method is called, but the return value is used as the size of the collection.</target>
1008+
<note />
1009+
</trans-unit>
1010+
<trans-unit id="SizeOfCollectionMustBeKnownAtMarshalTimeTitle">
1011+
<source>The size of a collection that is marshalled to the callee must be defined when the method is called.</source>
1012+
<target state="new">The size of a collection that is marshalled to the callee must be defined when the method is called.</target>
1013+
<note />
1014+
</trans-unit>
10001015
<trans-unit id="StatefulMarshallerRequiresFreeDescription">
10011016
<source>A stateful marshaller must have a zero-parameter void-returning instance method named 'Free'.</source>
10021017
<target state="translated">상태 저장 마샬러에는 'Free'라는 0 매개 변수 반환 인스턴스 메서드가 있어야 합니다.</target>

0 commit comments

Comments
 (0)