Skip to content

Comments

Extensions: fix crash with targeted attribute on extension block#82463

Open
jcouv wants to merge 3 commits intodotnet:mainfrom
jcouv:extension-attribute
Open

Extensions: fix crash with targeted attribute on extension block#82463
jcouv wants to merge 3 commits intodotnet:mainfrom
jcouv:extension-attribute

Conversation

@jcouv
Copy link
Member

@jcouv jcouv commented Feb 19, 2026

Fixes #82445
Fixes #82444
Relates to feature #76130

Problem: Placing an attribute with a target specifier (such as [return: Obsolete]) on an extension block caused a crash in MatchAttributeTarget. The allowedTargets == None branch assumed only interactive/global symbols (Assembly/Module) could have no allowed targets, and threw on any other DefaultAttributeLocation value.
Extension blocks (which are types with AllowedAttributeLocations == None) hit the throwing branch.

Fix:

  1. Set DefaultAttributeLocation = None for extension types in SourceNamedTypeSymbol
  2. Handled None case in MatchAttributeTarget
  3. Unified the diagnostic reported for attribute on extension block, between the existing check [MyAttribute] extension(int i) and the new check [return: MyAttribute] extension(int i)

We should discuss whether one or both of these scenarios should use a warning instead of an error.

[return: My] // warning CS0657: 'return' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are 'type'. All attributes in this block will be ignored.
[fake: My] // warning CS0658: 'fake' is not a recognized attribute location. Valid attribute locations for this declaration are 'type'. All attributes in this block will be ignored.
class D
{
}

@jcouv jcouv self-assigned this Feb 19, 2026
@jcouv jcouv added Area-Compilers Feature - Extension Everything The extension everything feature labels Feb 19, 2026
@jcouv jcouv marked this pull request as ready for review February 20, 2026 01:16
@jcouv jcouv requested a review from a team as a code owner February 20, 2026 01:16

case AttributeLocation.None:
// No attributes are allowed on this declaration (e.g. extension blocks).
diagnostics.Add(ErrorCode.ERR_AttributeNotAllowedOnExtensionBlock, targetOpt.Identifier.GetLocation());
Copy link
Member

@jjonescz jjonescz Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the diagnostic is extension-specific. Should we update the comment (e.g. doesn't seem correct) and assert that the symbol is an extension? #Resolved

var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (3,6): error CS0592: Attribute 'System.Obsolete' is not valid on this declaration type. It is only valid on 'class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate' declarations.
// (3,6): error CS9360: Attributes are not allowed on extension blocks.
Copy link
Member

@jjonescz jjonescz Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is issue #82444 also fixed by this PR? #Resolved

AttributeLocation IAttributeTargetSymbol.DefaultAttributeLocation
{
get { return AttributeLocation.Type; }
get { return IsExtension ? AttributeLocation.None : AttributeLocation.Type; }
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AttributeLocation.None

We probably should add a dedicated location for an extension block #Resolved

var model = comp.GetSemanticModel(tree);
var type = tree.GetRoot().DescendantNodes().OfType<ExtensionBlockDeclarationSyntax>().Single();
var symbol = model.GetDeclaredSymbol(type);
AssertEx.SetEqual([], symbol.GetAttributes().Select(a => a.ToString()));
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.Select(a => a.ToString())

Is this needed? #Resolved

var model = comp.GetSemanticModel(tree);
var type = tree.GetRoot().DescendantNodes().OfType<ExtensionBlockDeclarationSyntax>().Single();
var symbol = model.GetDeclaredSymbol(type);
AssertEx.SetEqual([], symbol.GetAttributes().Select(a => a.ToString()));
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.Select(a => a.ToString())

Is this needed? #Resolved

var model = comp.GetSemanticModel(tree);
var type = tree.GetRoot().DescendantNodes().OfType<ExtensionBlockDeclarationSyntax>().Single();
var symbol = model.GetDeclaredSymbol(type);
AssertEx.SetEqual([], symbol.TypeParameters[0].GetAttributes().Select(a => a.ToString()));
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.Select(a => a.ToString())

Is this needed? #Resolved

var model = comp.GetSemanticModel(tree);
var type = tree.GetRoot().DescendantNodes().OfType<ExtensionBlockDeclarationSyntax>().Single();
var symbol = model.GetDeclaredSymbol(type);
AssertEx.SetEqual([], symbol.GetAttributes().Select(a => a.ToString()));
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.Select(a => a.ToString())

Is this needed? #Resolved

comp.VerifyEmitDiagnostics(
// (3,6): warning CS0658: 'fake' is not a recognized attribute location. Valid attribute locations for this declaration are ''. All attributes in this block will be ignored.
// [fake: My]
Diagnostic(ErrorCode.WRN_InvalidAttributeLocation, "fake").WithArguments("fake", "").WithLocation(3, 6));
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WRN_InvalidAttributeLocation

I think it would be better to report ERR_AttributeNotAllowedOnExtensionBlock here as well #Resolved

@AlekseyTs
Copy link
Contributor

Done with review pass (commit 1)

@jcouv jcouv requested review from AlekseyTs and jjonescz February 21, 2026 06:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Compilers Feature - Extension Everything The extension everything feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Targeted attribute list on extension block causes compiler crash Adding attributes to extension block has uninformative error message

3 participants