Skip to content

Commit c7eb44d

Browse files
Fix edge cases of getting attribute data from syntax (#75727)
Co-authored-by: Stephen Toub <[email protected]>
1 parent eeef4b1 commit c7eb44d

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/SyntaxExtensions.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,17 @@ public static Location FindTypeExpressionOrNullLocation(this AttributeArgumentSy
3333
switch (attributeTarget.Identifier.Kind())
3434
{
3535
case SyntaxKind.ReturnKeyword:
36-
return ((IMethodSymbol)targetSymbol).GetReturnTypeAttributes().First(attributeSyntaxLocationMatches);
36+
if (targetSymbol is IMethodSymbol method)
37+
{
38+
// Sometimes an attribute is put on a symbol that is nested within the containing symbol.
39+
// For example, the ContainingSymbol for an AttributeSyntax on a local function has a ContainingSymbol of the method.
40+
// Since this method is internal and the callers don't care about attributes on local functions,
41+
// we just allow this method to return null in those cases.
42+
return method.GetReturnTypeAttributes().FirstOrDefault(attributeSyntaxLocationMatches);
43+
}
44+
// An attribute on the return value of a delegate type's Invoke method has a ContainingSymbol of the delegate type.
45+
// We don't care about the attributes in this case for the callers, so we'll just return null.
46+
return null;
3747
case SyntaxKind.AssemblyKeyword:
3848
return targetSymbol.ContainingAssembly.GetAttributes().First(attributeSyntaxLocationMatches);
3949
case SyntaxKind.ModuleKeyword:
@@ -43,7 +53,8 @@ public static Location FindTypeExpressionOrNullLocation(this AttributeArgumentSy
4353
}
4454
}
4555
// Sometimes an attribute is put on a symbol that is nested within the containing symbol.
46-
// For example, the ContainingSymbol for an AttributeSyntax on a parameter have a ContainingSymbol of the method.
56+
// For example, the ContainingSymbol for an AttributeSyntax on a parameter has a ContainingSymbol of the method
57+
// and an AttributeSyntax on a local function has a ContainingSymbol of the containing method.
4758
// Since this method is internal and the callers don't care about attributes on parameters, we just allow
4859
// this method to return null in those cases.
4960
return targetSymbol.GetAttributes().FirstOrDefault(attributeSyntaxLocationMatches);

src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/NativeMarshallingAttributeAnalyzerTests.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,18 @@ public class X
272272
{
273273
void Foo([MarshalAs(UnmanagedType.I4)] int i)
274274
{
275+
[return:MarshalAs(UnmanagedType.I4)]
276+
[SkipLocalsInit]
277+
static int Local()
278+
{
279+
return 0;
280+
}
275281
}
276282
}
283+
284+
[return:MarshalAs(UnmanagedType.I4)]
285+
delegate int Y();
286+
277287
""";
278288

279289
await VerifyCS.VerifyAnalyzerAsync(source);

0 commit comments

Comments
 (0)