Conversation
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
|
It seems Copilot could not make a fix before timing out. |
Add tests verifying that SYSLIB1051 (ParameterTypeNotSupported) is correctly reported for StringBuilder parameters when StringMarshalling is set to Utf16 or Utf8, both as standalone parameters and alongside string parameters with [Out] attribute. Regression test for #126687 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@danmoseley I had copilot crank locally for quite a while and it couldn't figure it out but it did add some regression tests that should cover your scenario and pass without any product changes. Can you get me a complog of your build that didn't report the diagnostic? Is it possible that you have |
There was a problem hiding this comment.
Pull request overview
This PR targets a regression in LibraryImportDiagnosticsAnalyzer where SYSLIB1051 is not reported for StringBuilder parameters when LibraryImportAttribute.StringMarshalling is specified, leading to silently incorrect forwarder stub generation.
Changes:
- Added analyzer unit tests asserting SYSLIB1051 (
ParameterTypeNotSupported) is reported forStringBuilderparameters withStringMarshallingset (Utf16/Utf8) and without it. - Added a reproduction-style test case for
string+[Out] StringBuilderparameter combinations.
...braries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Diagnostics.cs
Show resolved
Hide resolved
...braries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Diagnostics.cs
Outdated
Show resolved
Hide resolved
This comment has been minimized.
This comment has been minimized.
@jkoritzinsky I updated the repro (top post #126687) to include a global.json -- can you still not repro with that? |
|
@jkoritzinsky also added the install command for preview 3. Using preview 2, it doesn't repro. I verified this by hand again, and it does repro for me with global.json pointing to 11.0.100-preview.3.26170.106 C:\temp\repro>type global.json | find /i "ver"
"version": "11.0.100-preview.3.26170.106",
C:\temp\repro>type program.cs
using System;
using System.Runtime.InteropServices;
using System.Text;
Console.WriteLine("If you see this, SYSLIB1051 was NOT reported.");
static partial class NativeMethods
{
[LibraryImport("kernel32.dll", StringMarshalling = StringMarshalling.Utf16)]
internal static partial int GetVolumeNameForVolumeMountPointW(
string volumeMountPoint,
[Out] StringBuilder volumeName,
int bufferLength);
}
C:\temp\repro>dotnet build
Restore complete (0.3s)
info NETSDK1057: You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
doit net11.0 succeeded (0.1s) → bin\Debug\net11.0\doit.dll
Build succeeded in 0.9s
and |
If I understand right then there are two bugs -- the error no longer firing, and the generated code not working (as I discovered in my original PR) the issue with the generated code pasted above (I think) is that it doesn't have |
…16 is set When LibraryImportGenerator creates a non-forwarder stub with an inner local DllImport function, it did not forward StringMarshalling.Utf16 as CharSet=Unicode. This caused any types forwarded to the runtime marshaller (e.g. StringBuilder) to default to Ansi encoding, producing incorrect results for Unicode APIs. Add CharSet=CharSet.Unicode to the inner DllImport attribute when StringMarshalling.Utf16 is specified on the LibraryImport, matching the existing behavior in CreateForwarderDllImport. Fix for #126687 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…te on the stub implementation, the user part of the partial is also marked as generated code. We don't need to pass ReportDiagnostics here as we will report diagnostics in the user part.
|
@danmoseley I found the bug. Apparently the analyzer wasn't firing because the source-generated code was marking the user part of the LibraryImport as generated and skipping it. I've updated the analyzer to catch this case. I've also added logic to forward CharSet.Unicode when needed in the forwarder. |
…rtGenerator.UnitTests/Diagnostics.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs
Outdated
Show resolved
Hide resolved
...braries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Diagnostics.cs
Show resolved
Hide resolved
...ime.InteropServices/gen/LibraryImportGenerator/Analyzers/LibraryImportDiagnosticsAnalyzer.cs
Show resolved
Hide resolved
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| AttributeArgumentSyntax? charSetArgument = dllImportAttr.ArgumentList!.Arguments | ||
| .SingleOrDefault(a => a.NameEquals?.Name.Identifier.Text == nameof(DllImportAttribute.CharSet)); | ||
|
|
||
| if (_expectCharSetUnicode) | ||
| { | ||
| Assert.NotNull(charSetArgument); | ||
| Assert.Equal($"{nameof(CharSet)}.{nameof(CharSet.Unicode)}", charSetArgument.Expression.ToString()); | ||
| } |
| public override void Initialize(AnalysisContext context) | ||
| { | ||
| context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); | ||
| context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze); |
There was a problem hiding this comment.
BTW, if you have .Analyze do you also want | CodeAnalysisFlags.ReportDiagnostics
There was a problem hiding this comment.
We don't want ReportDiagnostics as we aren't reporting diagnostics in generated source files. We're reporting in user source.
To my understanding, what's blocking us here is the concept of "generated source symbols" not locations.
| MemberAccessExpression( | ||
| SyntaxKind.SimpleMemberAccessExpression, | ||
| AliasQualifiedName("global", IdentifierName(typeof(CharSet).FullName)), | ||
| IdentifierName(nameof(CharSet.Unicode))))); |
|
@jeffhandley do you own the code review agent nowadays? this is not the first time I've seen it time out:
That blocks the PR being merged BTW edit: I merged some changes to fix/improve this |
jtschuster
left a comment
There was a problem hiding this comment.
This change looks good, but do we have a similar issue in the ComInterfaceGenerator?
|
Note This review was generated by Copilot (Claude Opus 4.6), with cross-validation from Claude Sonnet 4.5. 🤖 Copilot Code Review — PR #126691Holistic AssessmentMotivation: The PR addresses a real bug where Approach: The core generator fix is correct and mirrors the existing forwarder path. The analyzer change ( Summary: Detailed Findings
|
|
The trigger attribute isn't applied to a member that we put the GeneratedCodeAttribute on with the COM source generator, so this isn't a problem there. |
|
@copilot please fix for the DownlevelLibraryImportGenerator and its corresponding analyzer as well |
…nalyze, forward CharSet=Unicode, fix test assertion Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/485e2525-7401-4b45-a60d-6f22059d1482 Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Applied the same two fixes to the
Also fixed a test assertion ( |
Description
LibraryImportDiagnosticsAnalyzerandDownlevelLibraryImportDiagnosticsAnalyzerfail to report diagnostics (e.g. SYSLIB1051) for[LibraryImport]methods whenStringMarshallingis set. This is a regression introduced in preview.3 when diagnostic reporting was moved from the generators to separate analyzer classes. Additionally, the generated inner[DllImport]stub omitsCharSet = CharSet.UnicodewhenStringMarshalling.Utf16is set, causing incorrect runtime marshalling of forwarded types (e.g.StringBuilder).Root cause: The source generator marks its generated stub output with
[GeneratedCode]. Roslyn's generated-code heuristics then also classify the user'spartialmethod declaration as generated code. WithConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None), both analyzers silently skipped all[LibraryImport]methods.Reproduction:
Changes
LibraryImportDiagnosticsAnalyzer: ChangedGeneratedCodeAnalysisFlags.None→Analyzeso the analyzer runs on methods whose partial declaration is classified as generated code.DownlevelLibraryImportDiagnosticsAnalyzer: Applied the sameGeneratedCodeAnalysisFlags.Analyzefix.LibraryImportGenerator.CreateTargetDllImportAsLocalStatement: Now forwardsCharSet = CharSet.Unicodeto the inner[DllImport]whenStringMarshalling.Utf16is set, ensuring forwarded types use the correct encoding.DownlevelLibraryImportGenerator.CreateTargetDllImportAsLocalStatement: Applied the sameCharSet = CharSet.Unicodeforwarding fix.Diagnostics.cs): AddedStringBuilderNotSupported_ReportsDiagnosticandStringBuilderNotSupported_WithStringParam_ReportsDiagnosticregression tests coveringStringBuilderwith and withoutStringMarshallingvariants.Compiles.cs): AddedForwardedTypesWithStringMarshalling_InnerDllImportHasCharSettest verifying that the inner[DllImport]hasCharSet.UnicodewhenStringMarshalling.Utf16is set and noCharSetargument when other values are used. Fixed test assertion to useEndsWithto handle theglobal::qualified name emitted by the generator.Testing
LibraryImportGenerator,DownlevelLibraryImportGenerator) build successfully with zero errors and warnings.