Skip to content

Commit 12cfe7d

Browse files
authored
Don't emit friendly overload of Span<byte> param for flexible array structs (#1541)
1 parent 51614b6 commit 12cfe7d

File tree

2 files changed

+6
-3
lines changed

2 files changed

+6
-3
lines changed

src/Microsoft.Windows.CsWin32/Generator.FriendlyOverloads.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ private IEnumerable<MethodDeclarationSyntax> DeclareFriendlyOverload(
191191
bool isManagedParameterType = this.IsManagedType(parameterTypeInfo);
192192
MemorySize? memorySize = null;
193193
bool mustRemainAsPointer = false;
194+
bool isPointerToStructWithFlexibleArray = parameterTypeInfo is PointerTypeHandleInfo { ElementType: HandleTypeHandleInfo pointedElement } && pointedElement.Generator.IsStructWithFlexibleArray(pointedElement);
194195
if (this.FindInteropDecorativeAttribute(paramAttributes, MemorySizeAttribute) is CustomAttribute memorySizeAttribute)
195196
{
196197
memorySize = DecodeMemorySizeAttribute(memorySizeAttribute);
@@ -206,7 +207,7 @@ private IEnumerable<MethodDeclarationSyntax> DeclareFriendlyOverload(
206207
else if (memorySize is null)
207208
{
208209
// If there's no MemorySize attribute, we may still need to keep this parameter as a pointer if it's a struct with a flexible array.
209-
mustRemainAsPointer = parameterTypeInfo is PointerTypeHandleInfo { ElementType: HandleTypeHandleInfo pointedElement } && pointedElement.Generator.IsStructWithFlexibleArray(pointedElement);
210+
mustRemainAsPointer = isPointerToStructWithFlexibleArray;
210211
}
211212
else if (!improvePointersToSpansAndRefs)
212213
{
@@ -477,7 +478,7 @@ private IEnumerable<MethodDeclarationSyntax> DeclareFriendlyOverload(
477478
if (!isPointerToPointer && TryHandleCountParam(elementType, nullableSource: true))
478479
{
479480
// If we used a Span, we might also want to generate a struct helper.
480-
if (memorySize is not null)
481+
if (memorySize is not null && !isPointerToStructWithFlexibleArray)
481482
{
482483
countOfBytesStructParameters ??= new();
483484
countOfBytesStructParameters.Add(param);

test/CsWin32Generator.Tests/CsWin32GeneratorTests.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,15 @@ public async Task PointerReturnValueIsPreserved()
176176
["InitializeAcl", "InitializeAcl", "Span<byte> pAcl, winmdroot.Security.ACE_REVISION dwAclRevision"],
177177
// MemorySized-struct param should also have a version with `out struct` parameter.
178178
["InitializeAcl", "InitializeAcl", "out winmdroot.Security.ACL pAcl, winmdroot.Security.ACE_REVISION dwAclRevision"],
179-
["SetDefaultCommConfig", "SetDefaultCommConfig", "string lpszName, in winmdroot.Devices.Communication.COMMCONFIG lpCC"],
179+
["SetDefaultCommConfig", "SetDefaultCommConfig", "string lpszName, in winmdroot.Devices.Communication.COMMCONFIG lpCC", false],
180180
["ID3D11DeviceChild", "GetPrivateData", "this winmdroot.Graphics.Direct3D11.ID3D11DeviceChild @this, in global::System.Guid guid, ref uint pDataSize, Span<byte> pData"],
181181
["WriteFile", "WriteFile", "SafeHandle hFile, in byte lpBuffer, uint* lpNumberOfBytesWritten, global::System.Threading.NativeOverlapped* lpOverlapped", false],
182182
// All params included
183183
["SetupDiGetDeviceInterfaceDetail", "SetupDiGetDeviceInterfaceDetail", "SafeHandle DeviceInfoSet, in winmdroot.Devices.DeviceAndDriverInstallation.SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, Span<byte> DeviceInterfaceDetailData, out uint RequiredSize, ref winmdroot.Devices.DeviceAndDriverInstallation.SP_DEVINFO_DATA DeviceInfoData"],
184184
// Optional params omitted
185185
["SetupDiGetDeviceInterfaceDetail", "SetupDiGetDeviceInterfaceDetail", "SafeHandle DeviceInfoSet, in winmdroot.Devices.DeviceAndDriverInstallation.SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, Span<byte> DeviceInterfaceDetailData"],
186+
// We should _not_ have a struct param overload for flexible arrays
187+
["SetupDiGetDeviceInterfaceDetail", "SetupDiGetDeviceInterfaceDetail", "SafeHandle DeviceInfoSet, in winmdroot.Devices.DeviceAndDriverInstallation.SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, out winmdroot.Devices.DeviceAndDriverInstallation.SP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData, out uint RequiredSize, ref winmdroot.Devices.DeviceAndDriverInstallation.SP_DEVINFO_DATA DeviceInfoData", false],
186188
["WinHttpReadData", "WinHttpReadData", "void* hRequest, Span<byte> lpBuffer, ref uint lpdwNumberOfBytesRead"],
187189
["IsTextUnicode", "IsTextUnicode", "ReadOnlySpan<byte> lpv, ref winmdroot.Globalization.IS_TEXT_UNICODE_RESULT lpiResult"],
188190
// Omitted ref param

0 commit comments

Comments
 (0)