-
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
Changes from 1 commit
aa6b8de
565ef93
21c196b
3915323
77ef060
5767bd7
963f0b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,6 @@ | |
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
#nullable disable | ||
|
||
#if DEBUG | ||
// We use a struct rather than a class to represent the state for efficiency | ||
// for data flow analysis, with 32 bits of data inline. Merely copying the state | ||
|
@@ -59,20 +57,18 @@ internal partial class DefiniteAssignmentPass : LocalDataFlowPass< | |
/// <summary> | ||
/// Some variables that should be considered initially assigned. Used for region analysis. | ||
/// </summary> | ||
private readonly HashSet<Symbol> initiallyAssignedVariables; | ||
private readonly HashSet<Symbol>? initiallyAssignedVariables; | ||
|
||
/// <summary> | ||
/// Variables that were used anywhere, in the sense required to suppress warnings about | ||
/// unused variables. | ||
/// </summary> | ||
private readonly PooledHashSet<LocalSymbol> _usedVariables = PooledHashSet<LocalSymbol>.GetInstance(); | ||
|
||
#nullable enable | ||
/// <summary> | ||
/// Parameters of record primary constructors that were read anywhere. | ||
/// </summary> | ||
private PooledHashSet<ParameterSymbol>? _readParameters; | ||
#nullable disable | ||
|
||
/// <summary> | ||
/// Variables that were used anywhere, in the sense required to suppress warnings about | ||
|
@@ -105,12 +101,12 @@ internal partial class DefiniteAssignmentPass : LocalDataFlowPass< | |
/// <summary> | ||
/// The current source assembly. | ||
/// </summary> | ||
private readonly SourceAssemblySymbol _sourceAssembly; | ||
private readonly SourceAssemblySymbol? _sourceAssembly; | ||
|
||
/// <summary> | ||
/// A set of address-of expressions for which the operand is not definitely assigned. | ||
/// </summary> | ||
private readonly HashSet<PrefixUnaryExpressionSyntax> _unassignedVariableAddressOfSyntaxes; | ||
private readonly HashSet<PrefixUnaryExpressionSyntax>? _unassignedVariableAddressOfSyntaxes; | ||
|
||
/// <summary> | ||
/// Tracks variables for which we have already reported a definite assignment error. This | ||
|
@@ -136,7 +132,7 @@ internal partial class DefiniteAssignmentPass : LocalDataFlowPass< | |
/// <summary> | ||
/// The topmost method of this analysis. | ||
/// </summary> | ||
protected MethodSymbol topLevelMethod; | ||
protected MethodSymbol? topLevelMethod; | ||
|
||
protected bool _convertInsufficientExecutionStackExceptionToCancelledByStackGuardException = false; // By default, just let the original exception to bubble up. | ||
|
||
|
@@ -151,7 +147,7 @@ internal DefiniteAssignmentPass( | |
BoundNode node, | ||
bool strictAnalysis, | ||
bool trackUnassignments = false, | ||
HashSet<PrefixUnaryExpressionSyntax> unassignedVariableAddressOfSyntaxes = null, | ||
HashSet<PrefixUnaryExpressionSyntax>? unassignedVariableAddressOfSyntaxes = null, | ||
bool requireOutParamsAssigned = true, | ||
bool trackClassFields = false, | ||
bool trackStaticMembers = false) | ||
|
@@ -160,7 +156,7 @@ internal DefiniteAssignmentPass( | |
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 commentThe 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 |
||
_unassignedVariableAddressOfSyntaxes = unassignedVariableAddressOfSyntaxes; | ||
_requireOutParamsAssigned = requireOutParamsAssigned; | ||
_trackClassFields = trackClassFields; | ||
|
@@ -175,11 +171,11 @@ internal DefiniteAssignmentPass( | |
BoundNode node, | ||
EmptyStructTypeCache emptyStructs, | ||
bool trackUnassignments = false, | ||
HashSet<Symbol> initiallyAssignedVariables = null) | ||
HashSet<Symbol>? initiallyAssignedVariables = null) | ||
: base(compilation, member, node, emptyStructs, trackUnassignments) | ||
{ | ||
this.initiallyAssignedVariables = initiallyAssignedVariables; | ||
_sourceAssembly = ((object)member == null) ? null : (SourceAssemblySymbol)member.ContainingAssembly; | ||
_sourceAssembly = member?.ContainingAssembly as SourceAssemblySymbol; | ||
this.CurrentSymbol = member; | ||
_unassignedVariableAddressOfSyntaxes = null; | ||
_requireOutParamsAssigned = true; | ||
|
@@ -237,6 +233,7 @@ protected override int AddVariable(VariableIdentifier identifier) | |
return slot; | ||
} | ||
|
||
#nullable disable | ||
protected Symbol GetNonMemberSymbol(int slot) | ||
{ | ||
VariableIdentifier variableId = variableBySlot[slot]; | ||
|
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.