-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid assuming containing assembly is from source in DefiniteAssignment #59069
Conversation
@@ -160,7 +156,7 @@ internal partial class DefiniteAssignmentPass : LocalDataFlowPass< | |||
trackUnassignments) | |||
{ | |||
this.initiallyAssignedVariables = null; | |||
_sourceAssembly = ((object)member == null) ? null : (SourceAssemblySymbol)member.ContainingAssembly; | |||
_sourceAssembly = member?.ContainingAssembly as SourceAssemblySymbol; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is member in this case? And why is its assembly not from source? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The failure case is an expression within a lambda used as an attribute argument. The member in that case is the attribute (obtained from SyntaxTreeSemanticModel.GetMemberModel(expression)
) where the attribute type is from metadata.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fascinating. Can we add an assert that it's basically either this case, or from source (or the member is null altogether)? It feels like this could potentially hide a bug later on if another case slipped in here.
@@ -160,7 +156,7 @@ internal partial class DefiniteAssignmentPass : LocalDataFlowPass< | |||
trackUnassignments) | |||
{ | |||
this.initiallyAssignedVariables = null; | |||
_sourceAssembly = ((object)member == null) ? null : (SourceAssemblySymbol)member.ContainingAssembly; | |||
_sourceAssembly = member?.ContainingAssembly as SourceAssemblySymbol; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like we might want to strengthen the logic here to get ContainingAssembly
only from a symbol that is actually a member or belongs to a member. Otherwise, we might still get a SourceAssemblySymbol
that doesn't match the context and start changing its state based on the analysis that we perform. #Closed
Done with review pass (commit 1) |
(type.IsErrorType() || compilation.IsAttributeType(type))); | ||
return null; | ||
} | ||
Debug.Assert(member.ContainingAssembly is SourceAssemblySymbol); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, if we always have compilation
, why not simply always grab its SourceAssembly
regardless of the node
and member
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverting to use member.ContainingAssembly as SourceAssemblySymbol
rather than compilation.SourceAssembly
since compilation
may be null
in the EE. (It doesn't seem like we have any tests that hit this case currently, but it seems safer to allow that.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since
compilation
may be null in the EE.
This doesn't match the nullable annotations on the parameters. Also, we store compilation
in a protected field in the base class and it doesn't look like we protect against null
value in it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (commit 4)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (commit 6)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (commit 7), assuming that we will open an issue to ensure that flow analysis is never passed a null compilation.
Fixes #57428