Files
2026-08-27 10:56:38 -06:00

2772 lines
92 KiB
C#

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal class DefiniteAssignmentPass : LocalDataFlowPass<DefiniteAssignmentPass.LocalState, DefiniteAssignmentPass.LocalFunctionState>
{
private sealed class SameDiagnosticComparer : EqualityComparer<Diagnostic>
{
public static readonly SameDiagnosticComparer Instance = new SameDiagnosticComparer();
public override bool Equals(Diagnostic x, Diagnostic y)
{
return x.Equals(y);
}
public override int GetHashCode(Diagnostic obj)
{
return Hash.Combine(Hash.CombineValues<object>((IEnumerable<object>)obj.Arguments, int.MaxValue), Hash.Combine(((object)obj.Location).GetHashCode(), obj.Code));
}
}
internal struct LocalState : ILocalDataFlowState, ILocalState
{
internal BitVector Assigned;
public bool NormalizeToBottom { get; }
public bool Reachable
{
get
{
if (((BitVector)(ref Assigned)).Capacity > 0)
{
return !IsAssigned(0);
}
return true;
}
}
internal LocalState(BitVector assigned, bool normalizeToBottom = false)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
Assigned = assigned;
NormalizeToBottom = normalizeToBottom;
}
public LocalState Clone()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
return new LocalState(((BitVector)(ref Assigned)).Clone());
}
public bool IsAssigned(int slot)
{
return ((BitVector)(ref Assigned))[slot];
}
public void Assign(int slot)
{
if (slot != -1)
{
((BitVector)(ref Assigned))[slot] = true;
}
}
public void Unassign(int slot)
{
if (slot != -1)
{
((BitVector)(ref Assigned))[slot] = false;
}
}
}
internal sealed class LocalFunctionState(LocalState stateFromBottom, LocalState stateFromTop) : AbstractLocalFunctionState(stateFromBottom, stateFromTop)
{
public BitVector ReadVars = BitVector.Empty;
public BitVector CapturedMask = BitVector.Null;
public BitVector InvertedCapturedMask = BitVector.Null;
}
private readonly PooledDictionary<VariableIdentifier, int> _variableSlot = PooledDictionary<LocalDataFlowPass<LocalState, LocalFunctionState>.VariableIdentifier, int>.GetInstance();
protected readonly ArrayBuilder<VariableIdentifier> variableBySlot = ArrayBuilder<LocalDataFlowPass<LocalState, LocalFunctionState>.VariableIdentifier>.GetInstance(1, default(LocalDataFlowPass<LocalState, LocalFunctionState>.VariableIdentifier));
private readonly HashSet<Symbol>? initiallyAssignedVariables;
private readonly PooledHashSet<LocalSymbol> _usedVariables = PooledHashSet<LocalSymbol>.GetInstance();
private PooledHashSet<ParameterSymbol>? _readParameters;
private readonly PooledHashSet<LocalFunctionSymbol> _usedLocalFunctions = PooledHashSet<LocalFunctionSymbol>.GetInstance();
private readonly PooledHashSet<Symbol> _writtenVariables = PooledHashSet<Symbol>.GetInstance();
private PooledHashSet<FieldSymbol>? _implicitlyInitializedFieldsOpt;
private readonly PooledDictionary<Symbol, Location> _unsafeAddressTakenVariables = PooledDictionary<Symbol, Location>.GetInstance();
private readonly PooledHashSet<Symbol> _capturedVariables = PooledHashSet<Symbol>.GetInstance();
private readonly PooledHashSet<Symbol> _capturedInside = PooledHashSet<Symbol>.GetInstance();
private readonly PooledHashSet<Symbol> _capturedOutside = PooledHashSet<Symbol>.GetInstance();
private readonly SourceAssemblySymbol? _sourceAssembly;
private readonly HashSet<PrefixUnaryExpressionSyntax>? _unassignedVariableAddressOfSyntaxes;
private BitVector _alreadyReported;
private readonly bool _requireOutParamsAssigned;
private readonly bool _trackClassFields;
private readonly bool _trackStaticMembers;
protected MethodSymbol? topLevelMethod;
protected bool _convertInsufficientExecutionStackExceptionToCancelledByStackGuardException;
private readonly bool _shouldCheckConverted;
private bool TrackImplicitlyInitializedFields
{
get
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Invalid comparison between Unknown and I4
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Invalid comparison between Unknown and I4
if (_requireOutParamsAssigned && !_emptyStructTypeCache._dev12CompilerCompatibility)
{
Symbol currentSymbol = CurrentSymbol;
if (currentSymbol is MethodSymbol methodSymbol && (int)methodSymbol.MethodKind == 1)
{
NamedTypeSymbol containingType = currentSymbol.ContainingType;
if ((object)containingType != null)
{
return (int)containingType.TypeKind == 10;
}
}
return false;
}
return false;
}
}
public sealed override bool AwaitUsingAndForeachAddsPendingBranch => true;
private void AddImplicitlyInitializedField(FieldSymbol field)
{
if (TrackImplicitlyInitializedFields)
{
((HashSet<FieldSymbol>)(object)(_implicitlyInitializedFieldsOpt ?? (_implicitlyInitializedFieldsOpt = PooledHashSet<FieldSymbol>.GetInstance()))).Add(field);
}
}
internal DefiniteAssignmentPass(CSharpCompilation compilation, Symbol member, BoundNode node, bool strictAnalysis, bool trackUnassignments = false, HashSet<PrefixUnaryExpressionSyntax>? unassignedVariableAddressOfSyntaxes = null, bool requireOutParamsAssigned = true, bool trackClassFields = false, bool trackStaticMembers = false)
: base(compilation, member, node, strictAnalysis ? EmptyStructTypeCache.CreatePrecise() : EmptyStructTypeCache.CreateForDev12Compatibility(compilation), trackUnassignments)
{
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
initiallyAssignedVariables = null;
_sourceAssembly = GetSourceAssembly(compilation, member, node);
_unassignedVariableAddressOfSyntaxes = unassignedVariableAddressOfSyntaxes;
_requireOutParamsAssigned = requireOutParamsAssigned;
_trackClassFields = trackClassFields;
_trackStaticMembers = trackStaticMembers;
topLevelMethod = member as MethodSymbol;
_shouldCheckConverted = GetType() == typeof(DefiniteAssignmentPass);
State = new LocalState(BitVector.Empty);
}
internal DefiniteAssignmentPass(CSharpCompilation compilation, Symbol member, BoundNode node, EmptyStructTypeCache emptyStructs, bool trackUnassignments = false, HashSet<Symbol>? initiallyAssignedVariables = null)
: base(compilation, member, node, emptyStructs, trackUnassignments)
{
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
this.initiallyAssignedVariables = initiallyAssignedVariables;
_sourceAssembly = GetSourceAssembly(compilation, member, node);
CurrentSymbol = member;
_unassignedVariableAddressOfSyntaxes = null;
_requireOutParamsAssigned = true;
topLevelMethod = member as MethodSymbol;
_shouldCheckConverted = GetType() == typeof(DefiniteAssignmentPass);
State = new LocalState(BitVector.Empty);
}
internal DefiniteAssignmentPass(CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion, HashSet<Symbol> initiallyAssignedVariables, HashSet<PrefixUnaryExpressionSyntax> unassignedVariableAddressOfSyntaxes, bool trackUnassignments)
: base(compilation, member, node, EmptyStructTypeCache.CreateNeverEmpty(), firstInRegion, lastInRegion, true, trackUnassignments)
{
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
this.initiallyAssignedVariables = initiallyAssignedVariables;
_sourceAssembly = null;
CurrentSymbol = member;
_unassignedVariableAddressOfSyntaxes = unassignedVariableAddressOfSyntaxes;
_shouldCheckConverted = GetType() == typeof(DefiniteAssignmentPass);
State = new LocalState(BitVector.Empty);
}
private static SourceAssemblySymbol? GetSourceAssembly(CSharpCompilation compilation, Symbol member, BoundNode node)
{
if ((object)member == null)
{
return null;
}
if (node.Kind == BoundKind.Attribute)
{
return null;
}
return member.ContainingAssembly as SourceAssemblySymbol;
}
protected override void Free()
{
variableBySlot.Free();
_variableSlot.Free();
_usedVariables.Free();
_readParameters?.Free();
_implicitlyInitializedFieldsOpt?.Free();
_usedLocalFunctions.Free();
_writtenVariables.Free();
_capturedVariables.Free();
_capturedInside.Free();
_capturedOutside.Free();
_unsafeAddressTakenVariables.Free();
base.Free();
}
protected override bool TryGetVariable(VariableIdentifier identifier, out int slot)
{
return ((Dictionary<LocalDataFlowPass<LocalState, LocalFunctionState>.VariableIdentifier, int>)(object)_variableSlot).TryGetValue(identifier, out slot);
}
protected override int AddVariable(VariableIdentifier identifier)
{
int count = variableBySlot.Count;
((Dictionary<LocalDataFlowPass<LocalState, LocalFunctionState>.VariableIdentifier, int>)(object)_variableSlot).Add(identifier, count);
variableBySlot.Add(identifier);
return count;
}
protected Symbol GetNonMemberSymbol(int slot)
{
LocalDataFlowPass<LocalState, LocalFunctionState>.VariableIdentifier variableIdentifier = variableBySlot[slot];
while (variableIdentifier.ContainingSlot > 0)
{
variableIdentifier = variableBySlot[variableIdentifier.ContainingSlot];
}
return variableIdentifier.Symbol;
}
private int RootSlot(int slot)
{
while (true)
{
int containingSlot = variableBySlot[slot].ContainingSlot;
if (containingSlot == 0)
{
break;
}
slot = containingSlot;
}
return slot;
}
protected override bool ConvertInsufficientExecutionStackExceptionToCancelledByStackGuardException()
{
return _convertInsufficientExecutionStackExceptionToCancelledByStackGuardException;
}
protected override ImmutableArray<PendingBranch> Scan(ref bool badRegion)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
base.Diagnostics.Clear();
ImmutableArray<ParameterSymbol> methodParameters = base.MethodParameters;
ParameterSymbol methodThisParameter = base.MethodThisParameter;
_alreadyReported = BitVector.Empty;
regionPlace = RegionPlace.Before;
EnterParameters(methodParameters);
Symbol symbol = _symbol;
if (symbol is MethodSymbol methodSymbol)
{
if (!symbol.IsStatic && symbol.ContainingSymbol is SourceMemberContainerTypeSymbol sourceMemberContainerTypeSymbol)
{
SynthesizedPrimaryConstructor primaryConstructor = sourceMemberContainerTypeSymbol.PrimaryConstructor;
if ((object)primaryConstructor != null && !(methodSymbol is SynthesizedPrimaryConstructor))
{
Symbol currentSymbol = CurrentSymbol;
CurrentSymbol = primaryConstructor;
ImmutableArray<ParameterSymbol>.Enumerator enumerator = primaryConstructor.Parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSymbol current = enumerator.Current;
NoteWrite(current, null, read: true);
}
CurrentSymbol = currentSymbol;
}
}
}
else if ((symbol is FieldSymbol || symbol is PropertySymbol) && !symbol.IsStatic && symbol.ContainingSymbol is SourceMemberContainerTypeSymbol sourceMemberContainerTypeSymbol2)
{
SynthesizedPrimaryConstructor primaryConstructor = sourceMemberContainerTypeSymbol2.PrimaryConstructor;
if ((object)primaryConstructor != null)
{
SynthesizedPrimaryConstructor synthesizedPrimaryConstructor = primaryConstructor;
EnterParameters(synthesizedPrimaryConstructor.Parameters);
}
}
if ((object)methodThisParameter != null)
{
EnterParameter(methodThisParameter);
if ((int)methodThisParameter.Type.SpecialType != 0)
{
int orCreateSlot = GetOrCreateSlot(methodThisParameter);
SetSlotState(orCreateSlot, assigned: true);
}
}
ImmutableArray<AbstractFlowPass<LocalState, LocalFunctionState>.PendingBranch> result = base.Scan(ref badRegion);
if (ShouldAnalyzeOutParameters(out var location))
{
LeaveParameters(methodParameters, null, location);
if ((object)methodThisParameter != null)
{
LeaveParameter(methodThisParameter, null, location);
}
LocalState self = State;
ImmutableArray<AbstractFlowPass<LocalState, LocalFunctionState>.PendingBranch>.Enumerator enumerator2 = result.GetEnumerator();
while (enumerator2.MoveNext())
{
AbstractFlowPass<LocalState, LocalFunctionState>.PendingBranch current2 = enumerator2.Current;
State = current2.State;
LeaveParameters(methodParameters, current2.Branch.Syntax, null);
if ((object)methodThisParameter != null)
{
LeaveParameter(methodThisParameter, current2.Branch.Syntax, null);
}
Join(ref self, ref State);
}
State = self;
}
return result;
}
protected override ImmutableArray<PendingBranch> RemoveReturns()
{
ImmutableArray<AbstractFlowPass<LocalState, LocalFunctionState>.PendingBranch> immutableArray = base.RemoveReturns();
if (CurrentSymbol is MethodSymbol { IsAsync: not false, IsImplicitlyDeclared: false } && !immutableArray.Any((AbstractFlowPass<LocalState, LocalFunctionState>.PendingBranch pending) => HasAwait(pending)))
{
Location location = ((CurrentSymbol is LambdaSymbol lambdaSymbol) ? lambdaSymbol.DiagnosticLocation : CurrentSymbol.GetFirstLocationOrNone());
base.Diagnostics.Add(ErrorCode.WRN_AsyncLacksAwaits, location);
}
return immutableArray;
}
private static bool HasAwait(PendingBranch pending)
{
BoundNode branch = pending.Branch;
if (branch == null)
{
return false;
}
return branch.Kind switch
{
BoundKind.AwaitExpression => true,
BoundKind.UsingStatement => ((BoundUsingStatement)branch).AwaitOpt != null,
BoundKind.ForEachStatement => ((BoundForEachStatement)branch).AwaitOpt != null,
BoundKind.UsingLocalDeclarations => ((BoundUsingLocalDeclarations)branch).AwaitOpt != null,
_ => false,
};
}
protected virtual void ReportUnassignedOutParameter(ParameterSymbol parameter, SyntaxNode node, Location location)
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Invalid comparison between Unknown and I4
if ((!_requireOutParamsAssigned && (object)topLevelMethod == CurrentSymbol) || base.Diagnostics == null || !State.Reachable)
{
return;
}
if (location == (Location)null)
{
location = (Location)new SourceLocation(node);
}
bool flag = false;
if (parameter.IsThis)
{
int num = VariableSlot(parameter);
if (!State.IsAssigned(num))
{
TypeSymbol type = parameter.Type;
foreach (FieldSymbol structInstanceField in _emptyStructTypeCache.GetStructInstanceFields(type))
{
if (_emptyStructTypeCache.IsEmptyStructType(structInstanceField.Type) || LocalDataFlowPass<LocalState, LocalFunctionState>.HasInitializer(structInstanceField))
{
continue;
}
int num2 = VariableSlot(structInstanceField, num);
if (num2 == -1 || !State.IsAssigned(num2))
{
Symbol associatedSymbol = structInstanceField.AssociatedSymbol;
bool flag2 = (object)associatedSymbol != null && (int)associatedSymbol.Kind == 15;
if (compilation.IsFeatureEnabled(MessageID.IDS_FeatureAutoDefaultStructs))
{
base.Diagnostics.Add(flag2 ? ErrorCode.WRN_UnassignedThisAutoPropertySupportedVersion : ErrorCode.WRN_UnassignedThisSupportedVersion, location, flag2 ? associatedSymbol : structInstanceField);
}
else
{
base.Diagnostics.Add(flag2 ? ErrorCode.ERR_UnassignedThisAutoPropertyUnsupportedVersion : ErrorCode.ERR_UnassignedThisUnsupportedVersion, location, flag2 ? associatedSymbol : structInstanceField, new CSharpRequiredLanguageVersion(MessageID.IDS_FeatureAutoDefaultStructs.RequiredVersion()));
}
AddImplicitlyInitializedField(structInstanceField);
flag = true;
}
}
if (!flag)
{
if (type.HasInlineArrayAttribute(out var length) && length > 1)
{
FieldSymbol fieldSymbol = type.TryGetPossiblyUnsupportedByLanguageInlineArrayElementField();
if ((object)fieldSymbol != null)
{
if (!compilation.IsFeatureEnabled(MessageID.IDS_FeatureAutoDefaultStructs))
{
base.Diagnostics.Add(ErrorCode.ERR_ParamUnassigned, location, parameter.Name);
}
AddImplicitlyInitializedField(fieldSymbol);
}
}
flag = true;
}
}
}
if (!flag)
{
base.Diagnostics.Add(ErrorCode.ERR_ParamUnassigned, location, parameter.Name);
}
}
public static void Analyze(CSharpCompilation compilation, MethodSymbol member, BoundNode node, DiagnosticBag diagnostics, out ImmutableArray<FieldSymbol> implicitlyInitializedFieldsOpt, bool requireOutParamsAssigned)
{
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Invalid comparison between Unknown and I4
DiagnosticBag val;
(val, implicitlyInitializedFieldsOpt) = analyze(strictAnalysis: true);
if (!val.HasAnyErrors())
{
diagnostics.AddRangeAndFree(val);
return;
}
DiagnosticBag item = analyze(strictAnalysis: false).Item1;
if (item.AsEnumerable().Any((Diagnostic d) => d.Code == 8078))
{
diagnostics.AddRangeAndFree(item);
val.Free();
return;
}
if (val.Count == item.Count)
{
diagnostics.AddRangeAndFree(val);
item.Free();
return;
}
HashSet<Diagnostic> hashSet = new HashSet<Diagnostic>(item.AsEnumerable(), SameDiagnosticComparer.Instance);
item.Free();
foreach (Diagnostic item3 in val.AsEnumerable())
{
if ((int)item3.Severity != 3 || hashSet.Contains(item3))
{
diagnostics.Add(item3);
continue;
}
ErrorCode code = (ErrorCode)item3.Code;
ErrorCode code2 = code switch
{
ErrorCode.ERR_UnassignedThisAutoPropertyUnsupportedVersion => ErrorCode.WRN_UnassignedThisAutoPropertyUnsupportedVersion,
ErrorCode.ERR_UnassignedThisUnsupportedVersion => ErrorCode.WRN_UnassignedThisUnsupportedVersion,
ErrorCode.ERR_ParamUnassigned => ErrorCode.WRN_ParamUnassigned,
ErrorCode.ERR_UseDefViolationProperty => ErrorCode.WRN_UseDefViolationProperty,
ErrorCode.ERR_UseDefViolationField => ErrorCode.WRN_UseDefViolationField,
ErrorCode.ERR_UseDefViolationThisUnsupportedVersion => ErrorCode.WRN_UseDefViolationThisUnsupportedVersion,
ErrorCode.ERR_UseDefViolationPropertyUnsupportedVersion => ErrorCode.WRN_UseDefViolationPropertyUnsupportedVersion,
ErrorCode.ERR_UseDefViolationFieldUnsupportedVersion => ErrorCode.WRN_UseDefViolationFieldUnsupportedVersion,
ErrorCode.ERR_UseDefViolationOut => ErrorCode.WRN_UseDefViolationOut,
ErrorCode.ERR_UseDefViolation => ErrorCode.WRN_UseDefViolation,
_ => code,
};
DiagnosticWithInfo val2 = (DiagnosticWithInfo)(object)((item3 is DiagnosticWithInfo) ? item3 : null);
object[] array;
if (val2 != null)
{
DiagnosticInfo info = val2.Info;
if (info != null)
{
object[] arguments = info.Arguments;
array = arguments;
goto IL_024f;
}
}
array = item3.Arguments.ToArray();
goto IL_024f;
IL_024f:
object[] args = array;
diagnostics.Add(code2, item3.Location, args);
}
val.Free();
(DiagnosticBag, ImmutableArray<FieldSymbol> implicitlyInitializedFieldsOpt) analyze(bool strictAnalysis)
{
DiagnosticBag instance = DiagnosticBag.GetInstance();
ImmutableArray<FieldSymbol> item2 = default(ImmutableArray<FieldSymbol>);
DefiniteAssignmentPass definiteAssignmentPass = new DefiniteAssignmentPass(compilation, member, node, strictAnalysis, trackUnassignments: false, null, requireOutParamsAssigned)
{
_convertInsufficientExecutionStackExceptionToCancelledByStackGuardException = true
};
try
{
bool badRegion = false;
definiteAssignmentPass.Analyze(ref badRegion, instance);
PooledHashSet<FieldSymbol> implicitlyInitializedFieldsOpt2 = definiteAssignmentPass._implicitlyInitializedFieldsOpt;
if (implicitlyInitializedFieldsOpt2 != null)
{
ArrayBuilder<FieldSymbol> instance2 = ArrayBuilder<FieldSymbol>.GetInstance(((HashSet<FieldSymbol>)(object)implicitlyInitializedFieldsOpt2).Count);
foreach (FieldSymbol item4 in (HashSet<FieldSymbol>)(object)implicitlyInitializedFieldsOpt2)
{
instance2.Add(item4);
}
instance2.Sort((IComparer<FieldSymbol>)LexicalOrderSymbolComparer.Instance);
item2 = instance2.ToImmutableAndFree();
}
}
catch (CancelledByStackGuardException ex) when (diagnostics != null)
{
ex.AddAnError(instance);
}
finally
{
definiteAssignmentPass.Free();
}
return (instance, implicitlyInitializedFieldsOpt: item2);
}
}
protected void Analyze(ref bool badRegion, DiagnosticBag diagnostics)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Analyze(ref badRegion);
if (diagnostics == null)
{
return;
}
foreach (Symbol item in (HashSet<Symbol>)(object)_capturedVariables)
{
if (((Dictionary<Symbol, Location>)(object)_unsafeAddressTakenVariables).TryGetValue(item, out Location value) && (!(item is ParameterSymbol key) || !(item.ContainingSymbol is SynthesizedPrimaryConstructor synthesizedPrimaryConstructor) || !synthesizedPrimaryConstructor.GetCapturedParameters().ContainsKey(key)))
{
diagnostics.Add(ErrorCode.ERR_LocalCantBeFixedAndHoisted, value, item.Name);
}
}
diagnostics.AddRange(base.Diagnostics);
}
private void CheckCaptured(Symbol variable, ParameterSymbol? rangeVariableUnderlyingParameter = null)
{
if (CurrentSymbol is SourceMethodSymbol containingSymbol && Symbol.IsCaptured(rangeVariableUnderlyingParameter ?? variable, containingSymbol))
{
NoteCaptured(variable);
}
}
private void NoteCaptured(Symbol variable)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Invalid comparison between Unknown and I4
if (regionPlace == RegionPlace.Inside)
{
((HashSet<Symbol>)(object)_capturedInside).Add(variable);
((HashSet<Symbol>)(object)_capturedVariables).Add(variable);
}
else if ((int)variable.Kind != 16)
{
((HashSet<Symbol>)(object)_capturedOutside).Add(variable);
((HashSet<Symbol>)(object)_capturedVariables).Add(variable);
}
}
protected IEnumerable<Symbol> GetCapturedInside()
{
return ((IEnumerable<Symbol>)_capturedInside).ToArray();
}
protected IEnumerable<Symbol> GetCapturedOutside()
{
return ((IEnumerable<Symbol>)_capturedOutside).ToArray();
}
protected IEnumerable<Symbol> GetCaptured()
{
return ((IEnumerable<Symbol>)_capturedVariables).ToArray();
}
protected IEnumerable<Symbol> GetUnsafeAddressTaken()
{
return ((Dictionary<Symbol, Location>)(object)_unsafeAddressTakenVariables).Keys.ToArray();
}
protected IEnumerable<MethodSymbol> GetUsedLocalFunctions()
{
return ((IEnumerable<LocalFunctionSymbol>)_usedLocalFunctions).ToArray();
}
private void NotePrimaryConstructorParameterReadIfNeeded(Symbol symbol)
{
if (symbol is ParameterSymbol item && symbol.ContainingSymbol is SynthesizedPrimaryConstructor)
{
if (_readParameters == null)
{
_readParameters = PooledHashSet<ParameterSymbol>.GetInstance();
}
((HashSet<ParameterSymbol>)(object)_readParameters).Add(item);
}
}
protected virtual void NoteRead(Symbol variable, ParameterSymbol rangeVariableUnderlyingParameter = null)
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Invalid comparison between Unknown and I4
if (variable is LocalSymbol item)
{
((HashSet<LocalSymbol>)(object)_usedVariables).Add(item);
}
NotePrimaryConstructorParameterReadIfNeeded(variable);
if (variable is LocalFunctionSymbol item2)
{
((HashSet<LocalFunctionSymbol>)(object)_usedLocalFunctions).Add(item2);
}
if ((object)variable != null)
{
if ((object)_sourceAssembly != null && (int)variable.Kind == 6)
{
_sourceAssembly.NoteFieldAccess((FieldSymbol)variable.OriginalDefinition, read: true, write: false);
}
CheckCaptured(variable, rangeVariableUnderlyingParameter);
}
}
private void NoteRead(BoundNode fieldOrEventAccess)
{
BoundNode boundNode = fieldOrEventAccess;
while (boundNode != null)
{
switch (boundNode.Kind)
{
default:
return;
case BoundKind.FieldAccess:
{
BoundFieldAccess boundFieldAccess = (BoundFieldAccess)boundNode;
NoteRead(boundFieldAccess.FieldSymbol);
if (MayRequireTracking(boundFieldAccess.ReceiverOpt, boundFieldAccess.FieldSymbol))
{
boundNode = boundFieldAccess.ReceiverOpt;
break;
}
return;
}
case BoundKind.EventAccess:
{
BoundEventAccess boundEventAccess = (BoundEventAccess)boundNode;
FieldSymbol associatedField = boundEventAccess.EventSymbol.AssociatedField;
if ((object)associatedField != null)
{
NoteRead(associatedField);
if (MayRequireTracking(boundEventAccess.ReceiverOpt, associatedField))
{
boundNode = boundEventAccess.ReceiverOpt;
break;
}
return;
}
return;
}
case BoundKind.ThisReference:
NoteRead(base.MethodThisParameter);
return;
case BoundKind.Local:
NoteRead(((BoundLocal)boundNode).LocalSymbol);
return;
case BoundKind.Parameter:
NoteRead(((BoundParameter)boundNode).ParameterSymbol);
return;
case BoundKind.InlineArrayAccess:
boundNode = ((BoundInlineArrayAccess)boundNode).Expression;
break;
}
}
}
protected virtual void NoteWrite(Symbol variable, BoundExpression value, bool read)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Invalid comparison between Unknown and I4
if ((object)variable != null)
{
((HashSet<Symbol>)(object)_writtenVariables).Add(variable);
if ((object)_sourceAssembly != null && (int)variable.Kind == 6)
{
FieldSymbol fieldSymbol = (FieldSymbol)variable.OriginalDefinition;
_sourceAssembly.NoteFieldAccess(fieldSymbol, read && WriteConsideredUse(fieldSymbol.Type, value), write: true);
}
LocalSymbol localSymbol = variable as LocalSymbol;
if ((object)localSymbol != null && read && WriteConsideredUse(localSymbol.Type, value))
{
((HashSet<LocalSymbol>)(object)_usedVariables).Add(localSymbol);
}
CheckCaptured(variable);
}
}
internal static bool WriteConsideredUse(TypeSymbol type, BoundExpression value)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Invalid comparison between Unknown and I4
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Invalid comparison between Unknown and I4
if (value == null || value.HasAnyErrors)
{
return true;
}
if ((object)type != null && type.IsReferenceType && (int)type.SpecialType != 20)
{
if (type is ArrayTypeSymbol { IsSZArray: not false } arrayTypeSymbol)
{
TypeSymbol elementType = arrayTypeSymbol.ElementType;
if ((object)elementType != null && (int)elementType.SpecialType == 10)
{
goto IL_0059;
}
}
return value.ConstantValueOpt != ConstantValue.Null;
}
goto IL_0059;
IL_0059:
if ((object)type != null && type.IsPointerOrFunctionPointer())
{
return true;
}
if (value != null && value.ConstantValueOpt != null && value.Kind != BoundKind.InterpolatedString)
{
return false;
}
switch (value.Kind)
{
case BoundKind.Conversion:
{
BoundConversion boundConversion = (BoundConversion)value;
if (boundConversion.ConversionKind.IsUserDefinedConversion() || boundConversion.ConversionKind == ConversionKind.IntPtr)
{
return true;
}
return WriteConsideredUse(null, boundConversion.Operand);
}
case BoundKind.DefaultLiteral:
case BoundKind.DefaultExpression:
return false;
case BoundKind.ObjectCreationExpression:
{
BoundObjectCreationExpression boundObjectCreationExpression = (BoundObjectCreationExpression)value;
if (boundObjectCreationExpression.Constructor.IsImplicitlyDeclared)
{
return boundObjectCreationExpression.InitializerExpressionOpt != null;
}
return true;
}
case BoundKind.Utf8String:
case BoundKind.TupleLiteral:
case BoundKind.ConvertedTupleLiteral:
return false;
default:
return true;
}
}
private void NoteWrite(BoundExpression n, BoundExpression value, bool read)
{
while (n != null)
{
switch (n.Kind)
{
case BoundKind.FieldAccess:
{
BoundFieldAccess boundFieldAccess = (BoundFieldAccess)n;
if ((object)_sourceAssembly != null)
{
FieldSymbol originalDefinition2 = boundFieldAccess.FieldSymbol.OriginalDefinition;
_sourceAssembly.NoteFieldAccess(originalDefinition2, value == null || WriteConsideredUse(boundFieldAccess.FieldSymbol.Type, value), write: true);
}
if (MayRequireTracking(boundFieldAccess.ReceiverOpt, boundFieldAccess.FieldSymbol))
{
n = boundFieldAccess.ReceiverOpt;
if (n.Kind == BoundKind.Local)
{
((HashSet<LocalSymbol>)(object)_usedVariables).Add(((BoundLocal)n).LocalSymbol);
}
break;
}
return;
}
case BoundKind.EventAccess:
{
BoundEventAccess boundEventAccess = (BoundEventAccess)n;
FieldSymbol associatedField = boundEventAccess.EventSymbol.AssociatedField;
if ((object)associatedField != null)
{
if ((object)_sourceAssembly != null)
{
FieldSymbol originalDefinition = associatedField.OriginalDefinition;
_sourceAssembly.NoteFieldAccess(originalDefinition, value == null || WriteConsideredUse(associatedField.Type, value), write: true);
}
if (MayRequireTracking(boundEventAccess.ReceiverOpt, associatedField))
{
n = boundEventAccess.ReceiverOpt;
break;
}
return;
}
return;
}
case BoundKind.ThisReference:
NoteWrite(base.MethodThisParameter, value, read);
return;
case BoundKind.Local:
NoteWrite(((BoundLocal)n).LocalSymbol, value, read);
return;
case BoundKind.Parameter:
NoteWrite(((BoundParameter)n).ParameterSymbol, value, read);
return;
case BoundKind.RangeVariable:
NoteWrite(((BoundRangeVariable)n).Value, value, read);
return;
case BoundKind.InlineArrayAccess:
n = ((BoundInlineArrayAccess)n).Expression;
value = null;
break;
default:
return;
}
}
}
protected override void Normalize(ref LocalState state)
{
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Invalid comparison between Unknown and I4
int capacity = ((BitVector)(ref state.Assigned)).Capacity;
int count = variableBySlot.Count;
((BitVector)(ref state.Assigned)).EnsureCapacity(count);
for (int i = capacity; i < count; i++)
{
int containingSlot = variableBySlot[i].ContainingSlot;
bool flag = containingSlot > 0 && ((BitVector)(ref state.Assigned))[containingSlot] && (int)variableBySlot[containingSlot].Symbol.GetTypeOrReturnType().TypeKind == 10;
if (state.NormalizeToBottom && containingSlot == 0)
{
flag = true;
}
((BitVector)(ref state.Assigned))[i] = flag;
}
}
protected override bool TryGetReceiverAndMember(BoundExpression expr, out BoundExpression receiver, out Symbol member)
{
receiver = null;
member = null;
switch (expr.Kind)
{
case BoundKind.FieldAccess:
{
BoundFieldAccess boundFieldAccess = (BoundFieldAccess)expr;
FieldSymbol fieldSymbol = (FieldSymbol)(member = boundFieldAccess.FieldSymbol);
if (fieldSymbol.IsFixedSizeBuffer)
{
return false;
}
if (fieldSymbol.IsStatic)
{
return _trackStaticMembers;
}
receiver = boundFieldAccess.ReceiverOpt;
break;
}
case BoundKind.EventAccess:
{
BoundEventAccess boundEventAccess = (BoundEventAccess)expr;
EventSymbol eventSymbol = boundEventAccess.EventSymbol;
member = eventSymbol.AssociatedField;
if (eventSymbol.IsStatic)
{
return _trackStaticMembers;
}
receiver = boundEventAccess.ReceiverOpt;
break;
}
case BoundKind.PropertyAccess:
{
BoundPropertyAccess boundPropertyAccess = (BoundPropertyAccess)expr;
if (Binder.AccessingAutoPropertyFromConstructor(boundPropertyAccess, CurrentSymbol))
{
PropertySymbol propertySymbol = boundPropertyAccess.PropertySymbol;
member = (propertySymbol as SourcePropertySymbolBase)?.BackingField;
if ((object)member == null)
{
return false;
}
if (propertySymbol.IsStatic)
{
return _trackStaticMembers;
}
receiver = boundPropertyAccess.ReceiverOpt;
}
break;
}
}
if ((object)member != null && receiver != null && receiver.Kind != BoundKind.TypeExpression)
{
return MayRequireTrackingReceiverType(receiver.Type);
}
return false;
}
private bool MayRequireTrackingReceiverType(TypeSymbol type)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Invalid comparison between Unknown and I4
if ((object)type != null)
{
if (!_trackClassFields)
{
return (int)type.TypeKind == 10;
}
return true;
}
return false;
}
protected bool MayRequireTracking(BoundExpression receiverOpt, FieldSymbol fieldSymbol)
{
if ((object)fieldSymbol != null && receiverOpt != null && !fieldSymbol.IsStatic && !fieldSymbol.IsFixedSizeBuffer && receiverOpt.Kind != BoundKind.TypeExpression && MayRequireTrackingReceiverType(receiverOpt.Type))
{
return !receiverOpt.Type.IsPrimitiveRecursiveStruct();
}
return false;
}
protected void CheckAssigned(Symbol symbol, SyntaxNode node)
{
if ((object)symbol == null)
{
return;
}
NoteRead(symbol);
if (State.Reachable)
{
int num = VariableSlot(symbol);
if (num >= ((BitVector)(ref State.Assigned)).Capacity)
{
Normalize(ref State);
}
if (num > 0 && !State.IsAssigned(num))
{
ReportUnassignedIfNotCapturedInLocalFunction(symbol, node, num);
}
}
}
private void ReportUnassignedIfNotCapturedInLocalFunction(Symbol symbol, SyntaxNode node, int slot, bool skipIfUseBeforeDeclaration = true)
{
if (IsCapturedInLocalFunction(slot))
{
RecordReadInLocalFunction(slot);
}
else
{
ReportUnassigned(symbol, node, slot, skipIfUseBeforeDeclaration);
}
}
protected virtual void ReportUnassigned(Symbol symbol, SyntaxNode node, int slot, bool skipIfUseBeforeDeclaration)
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Invalid comparison between Unknown and I4
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Invalid comparison between Unknown and I4
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Invalid comparison between Unknown and I4
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Invalid comparison between Unknown and I4
DefiniteAssignmentPass definiteAssignmentPass = this;
SyntaxNode node2 = node;
if (slot <= 0 || symbol is LocalSymbol { IsConst: not false })
{
return;
}
if (slot >= ((BitVector)(ref _alreadyReported)).Capacity)
{
((BitVector)(ref _alreadyReported)).EnsureCapacity(variableBySlot.Count);
}
if (!skipIfUseBeforeDeclaration || (int)symbol.Kind != 8)
{
goto IL_008c;
}
Location val = symbol.TryGetFirstLocation();
if (val != null)
{
TextSpan val2 = node2.Span;
int end = ((TextSpan)(ref val2)).End;
val2 = val.SourceSpan;
if (end >= ((TextSpan)(ref val2)).Start)
{
goto IL_008c;
}
}
goto IL_015c;
IL_008c:
if (!((BitVector)(ref _alreadyReported))[slot] && !symbol.GetTypeOrReturnType().Type.IsErrorType())
{
string name = symbol.Name;
if ((int)symbol.Kind == 6)
{
addDiagnosticForStructField(slot, (FieldSymbol)symbol);
}
else if ((int)symbol.Kind == 13 && (int)((ParameterSymbol)symbol).RefKind == 2)
{
if (((ParameterSymbol)symbol).IsThis)
{
addDiagnosticForStructThis(symbol, slot);
}
else
{
base.Diagnostics.Add(ErrorCode.ERR_UseDefViolationOut, node2.Location, name);
}
}
else
{
base.Diagnostics.Add(ErrorCode.ERR_UseDefViolation, node2.Location, name);
}
}
goto IL_015c;
IL_015c:
((BitVector)(ref _alreadyReported))[slot] = true;
void addDiagnosticForStructField(int fieldSlot, FieldSymbol fieldSymbol)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Invalid comparison between Unknown and I4
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Invalid comparison between Unknown and I4
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Invalid comparison between Unknown and I4
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
Symbol associatedSymbol = fieldSymbol.AssociatedSymbol;
bool flag = (object)associatedSymbol != null && (int)associatedSymbol.Kind == 15;
string text = (flag ? associatedSymbol.Name : fieldSymbol.Name);
Symbol currentSymbol = CurrentSymbol;
if (currentSymbol is MethodSymbol methodSymbol && (int)methodSymbol.MethodKind == 1)
{
NamedTypeSymbol containingType = currentSymbol.ContainingType;
if ((object)containingType != null && (int)containingType.TypeKind == 10)
{
int orCreateSlot = GetOrCreateSlot(CurrentSymbol.EnclosingThisSymbol());
LocalDataFlowPass<LocalState, LocalFunctionState>.VariableIdentifier variableIdentifier;
while (true)
{
if (fieldSlot == 0)
{
base.Diagnostics.Add(flag ? ErrorCode.ERR_UseDefViolationProperty : ErrorCode.ERR_UseDefViolationField, node2.Location, text);
return;
}
variableIdentifier = variableBySlot[fieldSlot];
int containingSlot = variableIdentifier.ContainingSlot;
if (containingSlot == orCreateSlot)
{
break;
}
fieldSlot = containingSlot;
}
AddImplicitlyInitializedField((FieldSymbol)variableIdentifier.Symbol);
if ((int)fieldSymbol.RefKind != 0)
{
if (!flag)
{
base.Diagnostics.Add(ErrorCode.WRN_UseDefViolationRefField, node2.Location, text);
}
}
else if (compilation.IsFeatureEnabled(MessageID.IDS_FeatureAutoDefaultStructs))
{
base.Diagnostics.Add(flag ? ErrorCode.WRN_UseDefViolationPropertySupportedVersion : ErrorCode.WRN_UseDefViolationFieldSupportedVersion, node2.Location, text);
}
else
{
base.Diagnostics.Add(flag ? ErrorCode.ERR_UseDefViolationPropertyUnsupportedVersion : ErrorCode.ERR_UseDefViolationFieldUnsupportedVersion, node2.Location, text, new CSharpRequiredLanguageVersion(MessageID.IDS_FeatureAutoDefaultStructs.RequiredVersion()));
}
return;
}
}
base.Diagnostics.Add(flag ? ErrorCode.ERR_UseDefViolationProperty : ErrorCode.ERR_UseDefViolationField, node2.Location, text);
}
void addDiagnosticForStructThis(Symbol thisParameter, int thisSlot)
{
if (TrackImplicitlyInitializedFields)
{
bool flag = false;
NamedTypeSymbol containingType = thisParameter.ContainingType;
foreach (FieldSymbol structInstanceField in _emptyStructTypeCache.GetStructInstanceFields(containingType))
{
if (!_emptyStructTypeCache.IsEmptyStructType(structInstanceField.Type) && !(structInstanceField is TupleErrorFieldSymbol))
{
int num = VariableSlot(structInstanceField, thisSlot);
if (num == -1 || !State.IsAssigned(num))
{
AddImplicitlyInitializedField(structInstanceField);
flag = true;
}
}
}
if (!flag && containingType.HasInlineArrayAttribute(out var length) && length > 1)
{
FieldSymbol fieldSymbol = containingType.TryGetPossiblyUnsupportedByLanguageInlineArrayElementField();
if ((object)fieldSymbol != null)
{
AddImplicitlyInitializedField(fieldSymbol);
flag = true;
}
}
}
if (compilation.IsFeatureEnabled(MessageID.IDS_FeatureAutoDefaultStructs))
{
base.Diagnostics.Add(ErrorCode.WRN_UseDefViolationThisSupportedVersion, node2.Location);
}
else
{
base.Diagnostics.Add(ErrorCode.ERR_UseDefViolationThisUnsupportedVersion, node2.Location, new CSharpRequiredLanguageVersion(MessageID.IDS_FeatureAutoDefaultStructs.RequiredVersion()));
}
}
}
protected virtual void CheckAssigned(BoundExpression expr, FieldSymbol fieldSymbol, SyntaxNode node)
{
if (State.Reachable && !IsAssigned(expr, out var unassignedSlot))
{
ReportUnassignedIfNotCapturedInLocalFunction(fieldSymbol, node, unassignedSlot);
}
NoteRead(expr);
}
private bool IsAssigned(BoundExpression node, out int unassignedSlot)
{
unassignedSlot = -1;
if (_emptyStructTypeCache.IsEmptyStructType(node.Type))
{
return true;
}
switch (node.Kind)
{
case BoundKind.ThisReference:
if ((object)base.MethodThisParameter == null)
{
unassignedSlot = -1;
return true;
}
unassignedSlot = GetOrCreateSlot(base.MethodThisParameter);
break;
case BoundKind.Local:
unassignedSlot = GetOrCreateSlot(((BoundLocal)node).LocalSymbol);
break;
case BoundKind.FieldAccess:
{
BoundFieldAccess boundFieldAccess = (BoundFieldAccess)node;
if (!MayRequireTracking(boundFieldAccess.ReceiverOpt, boundFieldAccess.FieldSymbol) || IsAssigned(boundFieldAccess.ReceiverOpt, out unassignedSlot))
{
return true;
}
unassignedSlot = GetOrCreateSlot(boundFieldAccess.FieldSymbol, unassignedSlot);
break;
}
case BoundKind.EventAccess:
{
BoundEventAccess boundEventAccess = (BoundEventAccess)node;
if (!MayRequireTracking(boundEventAccess.ReceiverOpt, boundEventAccess.EventSymbol.AssociatedField) || IsAssigned(boundEventAccess.ReceiverOpt, out unassignedSlot))
{
return true;
}
unassignedSlot = GetOrCreateSlot(boundEventAccess.EventSymbol.AssociatedField, unassignedSlot);
break;
}
case BoundKind.InlineArrayAccess:
{
BoundInlineArrayAccess boundInlineArrayAccess = (BoundInlineArrayAccess)node;
return IsAssigned(boundInlineArrayAccess.Expression, out unassignedSlot);
}
case BoundKind.PropertyAccess:
{
BoundPropertyAccess boundPropertyAccess = (BoundPropertyAccess)node;
if (Binder.AccessingAutoPropertyFromConstructor(boundPropertyAccess, CurrentSymbol))
{
SynthesizedBackingFieldSymbol synthesizedBackingFieldSymbol = (boundPropertyAccess.PropertySymbol as SourcePropertySymbolBase)?.BackingField;
if (synthesizedBackingFieldSymbol != null)
{
if (!MayRequireTracking(boundPropertyAccess.ReceiverOpt, synthesizedBackingFieldSymbol) || IsAssigned(boundPropertyAccess.ReceiverOpt, out unassignedSlot))
{
return true;
}
unassignedSlot = GetOrCreateSlot(synthesizedBackingFieldSymbol, unassignedSlot);
break;
}
}
goto default;
}
case BoundKind.Parameter:
{
BoundParameter boundParameter = (BoundParameter)node;
unassignedSlot = GetOrCreateSlot(boundParameter.ParameterSymbol);
break;
}
default:
unassignedSlot = -1;
return true;
}
if (unassignedSlot > 0)
{
return State.IsAssigned(unassignedSlot);
}
return true;
}
private Symbol UseNonFieldSymbolUnsafely(BoundExpression expression)
{
while (expression != null)
{
BoundFieldAccess boundFieldAccess;
switch (expression.Kind)
{
case BoundKind.FieldAccess:
{
boundFieldAccess = (BoundFieldAccess)expression;
FieldSymbol fieldSymbol = boundFieldAccess.FieldSymbol;
if ((object)_sourceAssembly != null)
{
_sourceAssembly.NoteFieldAccess(fieldSymbol, read: true, write: true);
}
if (fieldSymbol.ContainingType.IsReferenceType || fieldSymbol.IsStatic)
{
return null;
}
break;
}
case BoundKind.Local:
{
LocalSymbol localSymbol = ((BoundLocal)expression).LocalSymbol;
((HashSet<LocalSymbol>)(object)_usedVariables).Add(localSymbol);
return localSymbol;
}
case BoundKind.RangeVariable:
return ((BoundRangeVariable)expression).RangeVariableSymbol;
case BoundKind.Parameter:
return ((BoundParameter)expression).ParameterSymbol;
case BoundKind.ThisReference:
return base.MethodThisParameter;
case BoundKind.BaseReference:
return base.MethodThisParameter;
default:
return null;
}
expression = boundFieldAccess.ReceiverOpt;
}
return null;
}
protected void Assign(BoundNode node, BoundExpression value, bool isRef = false, bool read = true)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Invalid comparison between Unknown and I4
if (!isRef && node is BoundFieldAccess boundFieldAccess)
{
FieldSymbol fieldSymbol = boundFieldAccess.FieldSymbol;
if ((object)fieldSymbol != null && (int)fieldSymbol.RefKind != 0)
{
CheckAssigned(boundFieldAccess, node.Syntax);
}
}
AssignImpl(node, value, isRef, written: true, read);
}
protected virtual void AssignImpl(BoundNode node, BoundExpression value, bool isRef, bool written, bool read)
{
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_0276: Unknown result type (might be due to invalid IL or missing references)
//IL_027c: Invalid comparison between Unknown and I4
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Invalid comparison between Unknown and I4
BoundInlineArrayAccess boundInlineArrayAccess;
switch (node.Kind)
{
case BoundKind.DeclarationPattern:
case BoundKind.RecursivePattern:
case BoundKind.ListPattern:
{
BoundObjectPattern boundObjectPattern = (BoundObjectPattern)node;
if (boundObjectPattern.Variable is LocalSymbol symbol)
{
int orCreateSlot = GetOrCreateSlot(symbol);
SetSlotState(orCreateSlot, written || !State.Reachable);
}
if (written)
{
NoteWrite(boundObjectPattern.VariableAccess, value, read);
}
break;
}
case BoundKind.LocalDeclaration:
{
LocalSymbol localSymbol = ((BoundLocalDeclaration)node).LocalSymbol;
int orCreateSlot2 = GetOrCreateSlot(localSymbol);
SetSlotState(orCreateSlot2, written || !State.Reachable);
if (written)
{
NoteWrite(localSymbol, value, read);
}
break;
}
case BoundKind.Local:
{
BoundLocal boundLocal = (BoundLocal)node;
if ((int)boundLocal.LocalSymbol.RefKind != 0 && !isRef)
{
if (written)
{
VisitRvalue(boundLocal, isKnownToBeAnLvalue: true);
}
break;
}
int slot = MakeSlot(boundLocal);
SetSlotState(slot, written);
if (written)
{
NoteWrite(boundLocal, value, read);
}
break;
}
case BoundKind.InlineArrayAccess:
{
boundInlineArrayAccess = (BoundInlineArrayAccess)node;
if (written)
{
NoteWrite(boundInlineArrayAccess.Expression, null, read);
}
if (boundInlineArrayAccess.Expression.Type.HasInlineArrayAttribute(out var length))
{
ConstantValue constantValueOpt = boundInlineArrayAccess.Argument.ConstantValueOpt;
if (constantValueOpt == null || (int)constantValueOpt.SpecialType != 13 || constantValueOpt.Int32Value != 0)
{
SyntaxNode location;
int? num = Binder.InferConstantIndexFromSystemIndex(compilation, boundInlineArrayAccess.Argument, length, out location);
if ((num ?? 1) != 0)
{
goto IL_022c;
}
}
int num2 = MakeMemberSlot(boundInlineArrayAccess.Expression, boundInlineArrayAccess.Expression.Type.TryGetInlineArrayElementField());
if (num2 > 0)
{
SetSlotState(num2, written);
break;
}
}
goto IL_022c;
}
case BoundKind.Parameter:
{
BoundParameter boundParameter = (BoundParameter)node;
ParameterSymbol parameterSymbol = boundParameter.ParameterSymbol;
if (isRef && (int)parameterSymbol.RefKind == 2)
{
LeaveParameter(parameterSymbol, node.Syntax, boundParameter.Syntax.Location);
}
int slot4 = MakeSlot(boundParameter);
SetSlotState(slot4, written);
if (written)
{
NoteWrite(boundParameter, value, read);
}
break;
}
case BoundKind.ThisReference:
case BoundKind.FieldAccess:
case BoundKind.PropertyAccess:
case BoundKind.EventAccess:
{
BoundExpression boundExpression = (BoundExpression)node;
int slot3 = MakeSlot(boundExpression);
SetSlotState(slot3, written);
if (written)
{
NoteWrite(boundExpression, value, read);
}
break;
}
case BoundKind.RangeVariable:
AssignImpl(((BoundRangeVariable)node).Value, value, isRef, written, read);
break;
case BoundKind.BadExpression:
{
BoundBadExpression boundBadExpression = (BoundBadExpression)node;
if (!boundBadExpression.ChildBoundNodes.IsDefault && boundBadExpression.ChildBoundNodes.Length == 1)
{
AssignImpl(boundBadExpression.ChildBoundNodes[0], value, isRef, written, read);
}
break;
}
case BoundKind.TupleLiteral:
case BoundKind.ConvertedTupleLiteral:
{
((BoundTupleExpression)node).VisitAllElements(delegate(BoundExpression x, (DefiniteAssignmentPass self, bool isRef) arg)
{
arg.self.Assign(x, null, arg.isRef);
}, (this, isRef));
break;
}
IL_022c:
if (!written)
{
AssignImpl(boundInlineArrayAccess.Expression, null, isRef, written, read);
int slot2 = MakeSlot(boundInlineArrayAccess.Expression);
SetSlotState(slot2, written);
}
break;
}
}
private bool FieldsAllSet(int containingSlot, LocalState state)
{
TypeSymbol type = variableBySlot[containingSlot].Symbol.GetTypeOrReturnType().Type;
if (type.HasInlineArrayAttribute(out var length) && length > 1 && (object)type.TryGetPossiblyUnsupportedByLanguageInlineArrayElementField() != null)
{
return false;
}
foreach (FieldSymbol structInstanceField in _emptyStructTypeCache.GetStructInstanceFields(type))
{
if (!_emptyStructTypeCache.IsEmptyStructType(structInstanceField.Type) && !(structInstanceField is TupleErrorFieldSymbol))
{
int num = VariableSlot(structInstanceField, containingSlot);
if (num == -1 || !state.IsAssigned(num))
{
return false;
}
}
}
return true;
}
protected void SetSlotState(int slot, bool assigned)
{
if (slot > 0)
{
if (assigned)
{
SetSlotAssigned(slot);
}
else
{
SetSlotUnassigned(slot);
}
}
}
protected void SetSlotAssigned(int slot, ref LocalState state)
{
if (slot < 0)
{
return;
}
LocalDataFlowPass<LocalState, LocalFunctionState>.VariableIdentifier variableIdentifier = variableBySlot[slot];
TypeSymbol type = variableIdentifier.Symbol.GetTypeOrReturnType().Type;
if (slot >= ((BitVector)(ref state.Assigned)).Capacity)
{
Normalize(ref state);
}
if (state.IsAssigned(slot))
{
return;
}
state.Assign(slot);
if (EmptyStructTypeCache.IsTrackableStructType(type))
{
foreach (FieldSymbol structInstanceField in _emptyStructTypeCache.GetStructInstanceFields(type))
{
int num = VariableSlot(structInstanceField, slot);
if (num > 0)
{
SetSlotAssigned(num, ref state);
}
}
}
while (variableIdentifier.ContainingSlot > 0)
{
slot = variableIdentifier.ContainingSlot;
if (!state.IsAssigned(slot) && FieldsAllSet(slot, state))
{
state.Assign(slot);
variableIdentifier = variableBySlot[slot];
continue;
}
break;
}
}
private void SetSlotAssigned(int slot)
{
SetSlotAssigned(slot, ref State);
}
private void SetSlotUnassigned(int slot, ref LocalState state)
{
if (slot < 0)
{
return;
}
LocalDataFlowPass<LocalState, LocalFunctionState>.VariableIdentifier variableIdentifier = variableBySlot[slot];
TypeSymbol type = variableIdentifier.Symbol.GetTypeOrReturnType().Type;
if (!state.IsAssigned(slot))
{
return;
}
state.Unassign(slot);
if (EmptyStructTypeCache.IsTrackableStructType(type))
{
foreach (FieldSymbol structInstanceField in _emptyStructTypeCache.GetStructInstanceFields(type))
{
int num = VariableSlot(structInstanceField, slot);
if (num > 0)
{
SetSlotUnassigned(num, ref state);
}
}
}
while (variableIdentifier.ContainingSlot > 0)
{
slot = variableIdentifier.ContainingSlot;
state.Unassign(slot);
variableIdentifier = variableBySlot[slot];
}
}
private void SetSlotUnassigned(int slot)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
if (NonMonotonicState.HasValue)
{
LocalState state = NonMonotonicState.Value;
SetSlotUnassigned(slot, ref state);
NonMonotonicState = Optional<LocalState>.op_Implicit(state);
}
SetSlotUnassigned(slot, ref State);
}
protected override LocalState TopState()
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Invalid comparison between Unknown and I4
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Invalid comparison between Unknown and I4
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Invalid comparison between Unknown and I4
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Invalid comparison between Unknown and I4
LocalState state = new LocalState(BitVector.Empty);
Symbol symbol = CurrentSymbol;
while (true)
{
SymbolKind? val = symbol?.Kind;
bool flag;
if (val.HasValue)
{
SymbolKind valueOrDefault = val.GetValueOrDefault();
if ((int)valueOrDefault == 6 || (int)valueOrDefault == 9 || (int)valueOrDefault == 15)
{
flag = true;
goto IL_0172;
}
}
flag = false;
goto IL_0172;
IL_0172:
if (!flag)
{
break;
}
if ((object)symbol != CurrentSymbol && symbol is MethodSymbol { Parameters: var parameters } methodSymbol)
{
ImmutableArray<ParameterSymbol>.Enumerator enumerator = parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSymbol current = enumerator.Current;
int orCreateSlot = GetOrCreateSlot(current);
if (orCreateSlot > 0)
{
SetSlotAssigned(orCreateSlot, ref state);
}
}
if (methodSymbol.TryGetThisParameter(out var thisParameter) && (object)thisParameter != null)
{
int orCreateSlot2 = GetOrCreateSlot(thisParameter);
if (orCreateSlot2 > 0)
{
SetSlotAssigned(orCreateSlot2, ref state);
}
}
}
Symbol containingSymbol = symbol.ContainingSymbol;
if (!symbol.IsStatic && containingSymbol is SourceMemberContainerTypeSymbol sourceMemberContainerTypeSymbol)
{
SynthesizedPrimaryConstructor primaryConstructor = sourceMemberContainerTypeSymbol.PrimaryConstructor;
if ((object)primaryConstructor != null && (object)symbol != primaryConstructor)
{
ImmutableArray<ParameterSymbol>.Enumerator enumerator = primaryConstructor.Parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSymbol current2 = enumerator.Current;
int orCreateSlot3 = GetOrCreateSlot(current2);
if (orCreateSlot3 > 0)
{
if (!(symbol is MethodSymbol) && (int)current2.RefKind == 2)
{
SetSlotUnassigned(orCreateSlot3, ref state);
}
else
{
SetSlotAssigned(orCreateSlot3, ref state);
}
}
}
break;
}
}
symbol = containingSymbol;
}
return state;
}
protected override LocalState ReachableBottomState()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
LocalState result = new LocalState(BitVector.AllSet(variableBySlot.Count));
((BitVector)(ref result.Assigned))[0] = false;
return result;
}
protected override void EnterParameter(ParameterSymbol parameter)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Invalid comparison between Unknown and I4
int orCreateSlot = GetOrCreateSlot(parameter);
if ((int)parameter.RefKind == 2 && !(CurrentSymbol is MethodSymbol { IsAsync: not false }))
{
if (orCreateSlot > 0)
{
SetSlotState(orCreateSlot, initiallyAssignedVariables?.Contains(parameter) ?? false);
}
}
else
{
if (orCreateSlot > 0)
{
SetSlotState(orCreateSlot, assigned: true);
}
NoteWrite(parameter, null, read: true);
}
SourceComplexParameterSymbolBase sourceComplexParameterSymbolBase = parameter as SourceComplexParameterSymbolBase;
bool flag;
if ((object)sourceComplexParameterSymbolBase != null)
{
Symbol containingSymbol = sourceComplexParameterSymbolBase.ContainingSymbol;
if (containingSymbol is LocalFunctionSymbol || containingSymbol is LambdaSymbol)
{
flag = true;
goto IL_0089;
}
}
flag = false;
goto IL_0089;
IL_0089:
if (flag)
{
VisitAttributes(sourceComplexParameterSymbolBase.BindParameterAttributes());
BoundParameterEqualsValue boundParameterEqualsValue = sourceComplexParameterSymbolBase.BindParameterEqualsValue();
if (boundParameterEqualsValue != null)
{
VisitRvalue(boundParameterEqualsValue.Value);
}
}
}
private void VisitAttributes(ImmutableArray<(CSharpAttributeData, BoundAttribute)> boundAttributes)
{
if (boundAttributes.IsDefaultOrEmpty)
{
return;
}
ImmutableArray<(CSharpAttributeData, BoundAttribute)>.Enumerator enumerator = boundAttributes.GetEnumerator();
while (enumerator.MoveNext())
{
var (cSharpAttributeData, boundAttribute) = enumerator.Current;
if (!((AttributeData)cSharpAttributeData).HasErrors)
{
ImmutableArray<BoundExpression>.Enumerator enumerator2 = boundAttribute.ConstructorArguments.GetEnumerator();
while (enumerator2.MoveNext())
{
BoundExpression current = enumerator2.Current;
VisitRvalue(current);
}
ImmutableArray<BoundAssignmentOperator>.Enumerator enumerator3 = boundAttribute.NamedArguments.GetEnumerator();
while (enumerator3.MoveNext())
{
BoundAssignmentOperator current2 = enumerator3.Current;
VisitRvalue(current2.Right);
}
}
}
}
protected override void LeaveParameters(ImmutableArray<ParameterSymbol> parameters, SyntaxNode syntax, Location location)
{
if (State.Reachable)
{
base.LeaveParameters(parameters, syntax, location);
}
}
protected override void LeaveParameter(ParameterSymbol parameter, SyntaxNode syntax, Location location)
{
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Invalid comparison between Unknown and I4
if (!parameter.IsThis && (int)parameter.RefKind != 2 && parameter.ContainingSymbol is SynthesizedPrimaryConstructor synthesizedPrimaryConstructor)
{
PooledHashSet<ParameterSymbol>? readParameters = _readParameters;
if ((readParameters == null || !((HashSet<ParameterSymbol>)(object)readParameters).Contains(parameter)) && !synthesizedPrimaryConstructor.GetCapturedParameters().ContainsKey(parameter))
{
DiagnosticBag diagnostics = base.Diagnostics;
SourceMemberContainerTypeSymbol containingType = synthesizedPrimaryConstructor.ContainingType;
bool flag = (((object)containingType != null && (containingType.IsRecord || containingType.IsRecordStruct)) ? true : false);
diagnostics.Add(flag ? ErrorCode.WRN_UnreadRecordParameter : ErrorCode.WRN_UnreadPrimaryConstructorParameter, parameter.GetFirstLocationOrNone(), parameter.Name);
}
}
if ((int)parameter.RefKind != 0)
{
int num = VariableSlot(parameter);
if (num > 0 && !State.IsAssigned(num))
{
ReportUnassignedOutParameter(parameter, syntax, location);
}
NoteRead(parameter);
}
}
protected override LocalState UnreachableState()
{
LocalState result = State.Clone();
((BitVector)(ref result.Assigned)).EnsureCapacity(1);
result.Assign(0);
return result;
}
public override void VisitPattern(BoundPattern pattern)
{
base.VisitPattern(pattern);
LocalState stateWhenFalse = StateWhenFalse;
SetState(StateWhenTrue);
assignPatternVariablesAndMarkReadFields(pattern);
SetConditionalState(State, stateWhenFalse);
void assignPatternVariablesAndMarkReadFields(BoundPattern boundPattern, bool definitely = true)
{
switch (boundPattern.Kind)
{
case BoundKind.DeclarationPattern:
{
BoundDeclarationPattern node = (BoundDeclarationPattern)boundPattern;
if (definitely)
{
Assign(node, null, isRef: false, read: false);
}
break;
}
case BoundKind.SlicePattern:
{
BoundSlicePattern boundSlicePattern = (BoundSlicePattern)boundPattern;
if (boundSlicePattern.Pattern != null)
{
assignPatternVariablesAndMarkReadFields(boundSlicePattern.Pattern, definitely);
}
break;
}
case BoundKind.ConstantPattern:
{
BoundConstantPattern boundConstantPattern = (BoundConstantPattern)boundPattern;
VisitRvalue(boundConstantPattern.Value);
break;
}
case BoundKind.RecursivePattern:
{
BoundRecursivePattern boundRecursivePattern = (BoundRecursivePattern)boundPattern;
if (!boundRecursivePattern.Deconstruction.IsDefaultOrEmpty)
{
ImmutableArray<BoundPositionalSubpattern>.Enumerator enumerator = boundRecursivePattern.Deconstruction.GetEnumerator();
while (enumerator.MoveNext())
{
BoundPositionalSubpattern current3 = enumerator.Current;
assignPatternVariablesAndMarkReadFields(current3.Pattern, definitely);
}
}
if (!boundRecursivePattern.Properties.IsDefaultOrEmpty)
{
ImmutableArray<BoundPropertySubpattern>.Enumerator enumerator3 = boundRecursivePattern.Properties.GetEnumerator();
while (enumerator3.MoveNext())
{
BoundPropertySubpattern current4 = enumerator3.Current;
if ((object)_sourceAssembly != null)
{
for (BoundPropertySubpatternMember boundPropertySubpatternMember = current4.Member; boundPropertySubpatternMember != null; boundPropertySubpatternMember = boundPropertySubpatternMember.Receiver)
{
if (boundPropertySubpatternMember.Symbol is FieldSymbol field)
{
_sourceAssembly.NoteFieldAccess(field, read: true, write: false);
}
}
}
assignPatternVariablesAndMarkReadFields(current4.Pattern, definitely);
}
}
if (definitely)
{
Assign(boundRecursivePattern, null, isRef: false, read: false);
}
break;
}
case BoundKind.ITuplePattern:
{
ImmutableArray<BoundPositionalSubpattern>.Enumerator enumerator = ((BoundITuplePattern)boundPattern).Subpatterns.GetEnumerator();
while (enumerator.MoveNext())
{
BoundPositionalSubpattern current = enumerator.Current;
assignPatternVariablesAndMarkReadFields(current.Pattern, definitely);
}
break;
}
case BoundKind.ListPattern:
{
BoundListPattern boundListPattern = (BoundListPattern)boundPattern;
ImmutableArray<BoundPattern>.Enumerator enumerator2 = boundListPattern.Subpatterns.GetEnumerator();
while (enumerator2.MoveNext())
{
BoundPattern current2 = enumerator2.Current;
assignPatternVariablesAndMarkReadFields(current2, definitely);
}
if (definitely)
{
Assign(boundListPattern, null, isRef: false, read: false);
}
break;
}
case BoundKind.RelationalPattern:
{
BoundRelationalPattern boundRelationalPattern = (BoundRelationalPattern)boundPattern;
VisitRvalue(boundRelationalPattern.Value);
break;
}
case BoundKind.NegatedPattern:
{
BoundNegatedPattern boundNegatedPattern = (BoundNegatedPattern)boundPattern;
assignPatternVariablesAndMarkReadFields(boundNegatedPattern.Negated, definitely: false);
break;
}
case BoundKind.BinaryPattern:
{
BoundBinaryPattern boundBinaryPattern = (BoundBinaryPattern)boundPattern;
bool definitely2 = definitely && !boundBinaryPattern.Disjunction;
assignPatternVariablesAndMarkReadFields(boundBinaryPattern.Left, definitely2);
assignPatternVariablesAndMarkReadFields(boundBinaryPattern.Right, definitely2);
break;
}
default:
throw ExceptionUtilities.UnexpectedValue((object)boundPattern.Kind);
case BoundKind.DiscardPattern:
case BoundKind.TypePattern:
break;
}
}
}
public override BoundNode VisitBlock(BoundBlock node)
{
if (node.Instrumentation != null)
{
DeclareVariable(node.Instrumentation.Local);
Visit(node.Instrumentation.Prologue);
}
DeclareVariables(node.Locals);
VisitStatementsWithLocalFunctions(node);
ImmutableArray<LocalSymbol>.Enumerator enumerator = node.Locals.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current = enumerator.Current;
if (current.IsUsing)
{
NoteRead(current);
}
}
ReportUnusedVariables(node.Locals);
ReportUnusedVariables(node.LocalFunctions);
if (node.Instrumentation != null)
{
Visit(node.Instrumentation.Epilogue);
}
return null;
}
private void VisitStatementsWithLocalFunctions(BoundBlock block)
{
if (!TrackingRegions && !block.LocalFunctions.IsDefaultOrEmpty)
{
ImmutableArray<BoundStatement>.Enumerator enumerator = block.Statements.GetEnumerator();
while (enumerator.MoveNext())
{
BoundStatement current = enumerator.Current;
if (current is BoundLocalFunctionStatement boundLocalFunctionStatement)
{
VisitAttributes(boundLocalFunctionStatement.Symbol.BindMethodAttributes());
VisitAlways(current);
}
}
enumerator = block.Statements.GetEnumerator();
while (enumerator.MoveNext())
{
BoundStatement current2 = enumerator.Current;
if (current2.Kind != BoundKind.LocalFunctionStatement)
{
VisitStatement(current2);
}
}
}
else
{
ImmutableArray<BoundStatement>.Enumerator enumerator = block.Statements.GetEnumerator();
while (enumerator.MoveNext())
{
BoundStatement current3 = enumerator.Current;
VisitStatement(current3);
}
}
}
public override BoundNode VisitSwitchStatement(BoundSwitchStatement node)
{
DeclareVariables(node.InnerLocals);
BoundNode result = base.VisitSwitchStatement(node);
ReportUnusedVariables(node.InnerLocals);
ReportUnusedVariables(node.InnerLocalFunctions);
return result;
}
protected override void VisitSwitchSection(BoundSwitchSection node, bool isLastSection)
{
DeclareVariables(node.Locals);
base.VisitSwitchSection(node, isLastSection);
}
public override BoundNode VisitForStatement(BoundForStatement node)
{
DeclareVariables(node.OuterLocals);
DeclareVariables(node.InnerLocals);
BoundNode result = base.VisitForStatement(node);
ReportUnusedVariables(node.InnerLocals);
ReportUnusedVariables(node.OuterLocals);
return result;
}
public override BoundNode VisitDoStatement(BoundDoStatement node)
{
DeclareVariables(node.Locals);
BoundNode result = base.VisitDoStatement(node);
ReportUnusedVariables(node.Locals);
return result;
}
public override BoundNode VisitWhileStatement(BoundWhileStatement node)
{
DeclareVariables(node.Locals);
BoundNode result = base.VisitWhileStatement(node);
ReportUnusedVariables(node.Locals);
return result;
}
public override BoundNode VisitUsingStatement(BoundUsingStatement node)
{
ImmutableArray<LocalSymbol> locals = node.Locals;
DeclareVariables(locals);
BoundNode result = base.VisitUsingStatement(node);
if (!locals.IsDefaultOrEmpty)
{
ImmutableArray<LocalSymbol>.Enumerator enumerator = locals.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current = enumerator.Current;
if (current.DeclarationKind == LocalDeclarationKind.UsingVariable)
{
NoteRead(current);
}
}
}
return result;
}
public override BoundNode VisitFixedStatement(BoundFixedStatement node)
{
DeclareVariables(node.Locals);
return base.VisitFixedStatement(node);
}
public override BoundNode VisitSequence(BoundSequence node)
{
DeclareVariables(node.Locals);
BoundNode result = base.VisitSequence(node);
ReportUnusedVariables(node.Locals);
return result;
}
private void DeclareVariables(ImmutableArray<LocalSymbol> locals)
{
ImmutableArray<LocalSymbol>.Enumerator enumerator = locals.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current = enumerator.Current;
DeclareVariable(current);
}
}
private void DeclareVariable(LocalSymbol symbol)
{
bool assigned = symbol.IsConst || (initiallyAssignedVariables?.Contains(symbol) ?? false);
SetSlotState(GetOrCreateSlot(symbol), assigned);
}
private void ReportUnusedVariables(ImmutableArray<LocalSymbol> locals)
{
ImmutableArray<LocalSymbol>.Enumerator enumerator = locals.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current = enumerator.Current;
ReportIfUnused(current, assigned: true);
}
}
private void ReportIfUnused(LocalSymbol symbol, bool assigned)
{
if (!((HashSet<LocalSymbol>)(object)_usedVariables).Contains(symbol) && symbol.DeclarationKind != LocalDeclarationKind.PatternVariable && !string.IsNullOrEmpty(symbol.Name))
{
base.Diagnostics.Add((assigned && ((HashSet<Symbol>)(object)_writtenVariables).Contains((Symbol)symbol)) ? ErrorCode.WRN_UnreferencedVarAssg : ErrorCode.WRN_UnreferencedVar, symbol.GetFirstLocationOrNone(), symbol.Name);
}
}
private void ReportUnusedVariables(ImmutableArray<LocalFunctionSymbol> locals)
{
ImmutableArray<LocalFunctionSymbol>.Enumerator enumerator = locals.GetEnumerator();
while (enumerator.MoveNext())
{
LocalFunctionSymbol current = enumerator.Current;
ReportIfUnused(current);
}
}
private void ReportIfUnused(LocalFunctionSymbol symbol)
{
if (!((HashSet<LocalFunctionSymbol>)(object)_usedLocalFunctions).Contains(symbol) && !string.IsNullOrEmpty(symbol.Name))
{
base.Diagnostics.Add(ErrorCode.WRN_UnreferencedLocalFunction, symbol.GetFirstLocationOrNone(), symbol.Name);
}
}
public override BoundNode VisitLocal(BoundLocal node)
{
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Invalid comparison between Unknown and I4
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Expected O, but got Unknown
LocalSymbol localSymbol = node.LocalSymbol;
SourceLocalSymbol obj = localSymbol as SourceLocalSymbol;
if ((object)obj != null && obj.IsVar)
{
SyntaxNode forbiddenZone = localSymbol.ForbiddenZone;
if (forbiddenZone != null && forbiddenZone.Contains(node.Syntax))
{
int orCreateSlot = GetOrCreateSlot(node.LocalSymbol);
if (orCreateSlot > 0)
{
((BitVector)(ref _alreadyReported))[orCreateSlot] = true;
}
}
}
CheckAssigned(localSymbol, node.Syntax);
if (localSymbol.IsFixed && CurrentSymbol is MethodSymbol methodSymbol && ((int)methodSymbol.MethodKind == 0 || (int)methodSymbol.MethodKind == 17) && ((HashSet<Symbol>)(object)_capturedVariables).Contains((Symbol)localSymbol))
{
base.Diagnostics.Add(ErrorCode.ERR_FixedLocalInLambda, (Location)new SourceLocation(node.Syntax), localSymbol);
}
SplitIfBooleanConstant(node);
return null;
}
public override BoundNode VisitLocalDeclaration(BoundLocalDeclaration node)
{
GetOrCreateSlot(node.LocalSymbol);
HashSet<Symbol>? hashSet = initiallyAssignedVariables;
if (hashSet != null && hashSet.Contains(node.LocalSymbol))
{
Assign(node, null);
}
BoundNode result = base.VisitLocalDeclaration(node);
if (node.InitializerOpt != null)
{
Assign(node, node.InitializerOpt);
}
return result;
}
public override BoundNode VisitLocalId(BoundLocalId node)
{
return null;
}
public override BoundNode VisitParameterId(BoundParameterId node)
{
return null;
}
public override BoundNode VisitStateMachineInstanceId(BoundStateMachineInstanceId node)
{
return null;
}
public override BoundNode VisitMethodGroup(BoundMethodGroup node)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Invalid comparison between Unknown and I4
ImmutableArray<MethodSymbol>.Enumerator enumerator = node.Methods.GetEnumerator();
while (enumerator.MoveNext())
{
MethodSymbol current = enumerator.Current;
if ((int)current.MethodKind == 17)
{
((HashSet<LocalFunctionSymbol>)(object)_usedLocalFunctions).Add((LocalFunctionSymbol)current);
}
}
return base.VisitMethodGroup(node);
}
public override BoundNode VisitLambda(BoundLambda node)
{
Symbol currentSymbol = CurrentSymbol;
CurrentSymbol = node.Symbol;
VisitAttributes(node.Symbol.BindMethodAttributes());
AbstractFlowPass<LocalState, LocalFunctionState>.SavedPending oldPending = SavePending();
LocalState self = State;
State = (State.Reachable ? State.Clone() : ReachableBottomState());
if (!node.WasCompilerGenerated)
{
EnterParameters(node.Symbol.Parameters);
}
AbstractFlowPass<LocalState, LocalFunctionState>.SavedPending oldPending2 = SavePending();
VisitAlways(node.Body);
RestorePending(oldPending2);
ImmutableArray<AbstractFlowPass<LocalState, LocalFunctionState>.PendingBranch> immutableArray = RemoveReturns();
RestorePending(oldPending);
LeaveParameters(node.Symbol.Parameters, node.Syntax, null);
Join(ref self, ref State);
ImmutableArray<AbstractFlowPass<LocalState, LocalFunctionState>.PendingBranch>.Enumerator enumerator = immutableArray.GetEnumerator();
while (enumerator.MoveNext())
{
AbstractFlowPass<LocalState, LocalFunctionState>.PendingBranch current = enumerator.Current;
State = current.State;
if (current.Branch.Kind == BoundKind.ReturnStatement)
{
LeaveParameters(node.Symbol.Parameters, current.Branch.Syntax, null);
}
Join(ref self, ref State);
}
State = self;
CurrentSymbol = currentSymbol;
return null;
}
public override BoundNode VisitThisReference(BoundThisReference node)
{
CheckAssigned(base.MethodThisParameter, node.Syntax);
return null;
}
public override BoundNode VisitParameter(BoundParameter node)
{
if (!node.WasCompilerGenerated)
{
CheckAssigned(node.ParameterSymbol, node.Syntax);
}
else
{
NotePrimaryConstructorParameterReadIfNeeded(node.ParameterSymbol);
}
return null;
}
public override BoundNode VisitAssignmentOperator(BoundAssignmentOperator node)
{
base.VisitAssignmentOperator(node);
Assign(node.Left, node.Right, node.IsRef);
return null;
}
public override BoundNode VisitDeconstructionAssignmentOperator(BoundDeconstructionAssignmentOperator node)
{
base.VisitDeconstructionAssignmentOperator(node);
Assign(node.Left, node.Right);
return null;
}
public override BoundNode VisitIncrementOperator(BoundIncrementOperator node)
{
base.VisitIncrementOperator(node);
Assign(node.Operand, node);
return null;
}
public override BoundNode VisitCompoundAssignmentOperator(BoundCompoundAssignmentOperator node)
{
VisitCompoundAssignmentTarget(node);
VisitRvalue(node.Right);
AfterRightHasBeenVisited(node);
Assign(node.Left, node);
return null;
}
public override BoundNode VisitFixedLocalCollectionInitializer(BoundFixedLocalCollectionInitializer node)
{
BoundExpression boundExpression = node.Expression;
if (boundExpression.Kind == BoundKind.AddressOfOperator)
{
boundExpression = ((BoundAddressOfOperator)boundExpression).Operand;
}
VisitAddressOfOperand(boundExpression, shouldReadOperand: false);
return null;
}
public override BoundNode VisitAddressOfOperator(BoundAddressOfOperator node)
{
BoundExpression operand = node.Operand;
bool shouldReadOperand = false;
Symbol symbol = UseNonFieldSymbolUnsafely(operand);
if ((object)symbol != null)
{
HashSet<PrefixUnaryExpressionSyntax>? unassignedVariableAddressOfSyntaxes = _unassignedVariableAddressOfSyntaxes;
if (unassignedVariableAddressOfSyntaxes != null && !unassignedVariableAddressOfSyntaxes.Contains(node.Syntax as PrefixUnaryExpressionSyntax))
{
shouldReadOperand = true;
}
if (!((Dictionary<Symbol, Location>)(object)_unsafeAddressTakenVariables).ContainsKey(symbol))
{
((Dictionary<Symbol, Location>)(object)_unsafeAddressTakenVariables).Add(symbol, node.Syntax.Location);
}
}
VisitAddressOfOperand(node.Operand, shouldReadOperand);
return null;
}
protected override void WriteArgument(BoundExpression arg, RefKind refKind, MethodSymbol method)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Invalid comparison between Unknown and I4
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
if ((int)refKind == 1)
{
CheckAssigned(arg, arg.Syntax);
}
Assign(arg, null);
if ((int)refKind != 0 && ((object)method == null || method.IsExtern))
{
TypeSymbol type = arg.Type;
if ((object)type != null)
{
MarkFieldsUsed(type);
}
}
}
protected void CheckAssigned(BoundExpression expr, SyntaxNode node)
{
if (!State.Reachable)
{
return;
}
MakeSlot(expr);
switch (expr.Kind)
{
case BoundKind.Local:
CheckAssigned(((BoundLocal)expr).LocalSymbol, node);
break;
case BoundKind.Parameter:
CheckAssigned(((BoundParameter)expr).ParameterSymbol, node);
break;
case BoundKind.FieldAccess:
{
BoundFieldAccess boundFieldAccess = (BoundFieldAccess)expr;
FieldSymbol fieldSymbol = boundFieldAccess.FieldSymbol;
if (!fieldSymbol.IsFixedSizeBuffer && MayRequireTracking(boundFieldAccess.ReceiverOpt, fieldSymbol))
{
CheckAssigned(expr, fieldSymbol, node);
}
break;
}
case BoundKind.EventAccess:
{
BoundEventAccess boundEventAccess = (BoundEventAccess)expr;
FieldSymbol associatedField = boundEventAccess.EventSymbol.AssociatedField;
if ((object)associatedField != null && MayRequireTracking(boundEventAccess.ReceiverOpt, associatedField))
{
CheckAssigned(boundEventAccess, associatedField, node);
}
break;
}
case BoundKind.ThisReference:
case BoundKind.BaseReference:
CheckAssigned(base.MethodThisParameter, node);
break;
case BoundKind.InlineArrayAccess:
CheckAssigned(((BoundInlineArrayAccess)expr).Expression, node);
break;
}
}
private void MarkFieldsUsed(TypeSymbol type)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Invalid comparison between Unknown and I4
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Invalid comparison between Unknown and I4
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Invalid comparison between Unknown and I4
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Invalid comparison between Unknown and I4
TypeKind typeKind = type.TypeKind;
if ((int)typeKind != 1)
{
if (((int)typeKind != 2 && (int)typeKind != 10) || !type.IsFromCompilation(compilation) || !(type.ContainingAssembly is SourceAssemblySymbol sourceAssemblySymbol) || !sourceAssemblySymbol.TypesReferencedInExternalMethods.Add(type))
{
return;
}
ImmutableArray<Symbol>.Enumerator enumerator = ((NamedTypeSymbol)type).GetMembersUnordered().GetEnumerator();
while (enumerator.MoveNext())
{
Symbol current = enumerator.Current;
if ((int)current.Kind == 6)
{
FieldSymbol fieldSymbol = (FieldSymbol)current;
sourceAssemblySymbol.NoteFieldAccess(fieldSymbol, read: true, write: true);
MarkFieldsUsed(fieldSymbol.Type);
}
}
}
else
{
MarkFieldsUsed(((ArrayTypeSymbol)type).ElementType);
}
}
public override BoundNode VisitBaseReference(BoundBaseReference node)
{
CheckAssigned(base.MethodThisParameter, node.Syntax);
return null;
}
protected override void VisitCatchBlock(BoundCatchBlock catchBlock, ref LocalState finallyState)
{
DeclareVariables(catchBlock.Locals);
BoundExpression exceptionSourceOpt = catchBlock.ExceptionSourceOpt;
if (exceptionSourceOpt != null)
{
Assign(exceptionSourceOpt, null, isRef: false, read: false);
}
base.VisitCatchBlock(catchBlock, ref finallyState);
ImmutableArray<LocalSymbol>.Enumerator enumerator = catchBlock.Locals.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current = enumerator.Current;
ReportIfUnused(current, current.DeclarationKind != LocalDeclarationKind.CatchVariable);
}
}
public override BoundNode VisitFieldAccess(BoundFieldAccess node)
{
BoundNode result = base.VisitFieldAccess(node);
NoteRead(node.FieldSymbol);
if (node.FieldSymbol.IsFixedSizeBuffer && node.Syntax != null && !SyntaxFacts.IsFixedStatementExpression(node.Syntax))
{
Symbol symbol = UseNonFieldSymbolUnsafely(node.ReceiverOpt);
if ((object)symbol != null)
{
CheckCaptured(symbol);
if (!((Dictionary<Symbol, Location>)(object)_unsafeAddressTakenVariables).ContainsKey(symbol))
{
((Dictionary<Symbol, Location>)(object)_unsafeAddressTakenVariables).Add(symbol, node.Syntax.Location);
return result;
}
}
}
else if (MayRequireTracking(node.ReceiverOpt, node.FieldSymbol))
{
CheckAssigned(node, node.FieldSymbol, node.Syntax);
}
return result;
}
public override BoundNode VisitPropertyAccess(BoundPropertyAccess node)
{
BoundNode result = base.VisitPropertyAccess(node);
if (Binder.AccessingAutoPropertyFromConstructor(node, CurrentSymbol))
{
SynthesizedBackingFieldSymbol synthesizedBackingFieldSymbol = (node.PropertySymbol as SourcePropertySymbolBase)?.BackingField;
if (synthesizedBackingFieldSymbol != null && MayRequireTracking(node.ReceiverOpt, synthesizedBackingFieldSymbol) && State.Reachable && !IsAssigned(node, out var unassignedSlot))
{
ReportUnassignedIfNotCapturedInLocalFunction(synthesizedBackingFieldSymbol, node.Syntax, unassignedSlot);
}
}
return result;
}
public override BoundNode VisitEventAccess(BoundEventAccess node)
{
BoundNode result = base.VisitEventAccess(node);
FieldSymbol associatedField = node.EventSymbol.AssociatedField;
if ((object)associatedField != null)
{
NoteRead(associatedField);
if (MayRequireTracking(node.ReceiverOpt, associatedField))
{
CheckAssigned(node, associatedField, node.Syntax);
}
}
return result;
}
public override void VisitForEachIterationVariables(BoundForEachStatement node)
{
ImmutableArray<LocalSymbol>.Enumerator enumerator = node.IterationVariables.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current = enumerator.Current;
int orCreateSlot = GetOrCreateSlot(current);
if (orCreateSlot > 0)
{
SetSlotAssigned(orCreateSlot);
}
NoteWrite(current, null, read: true);
}
}
public override BoundNode VisitObjectInitializerMember(BoundObjectInitializerMember node)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Invalid comparison between Unknown and I4
BoundNode result = base.VisitObjectInitializerMember(node);
if ((object)_sourceAssembly != null && node.MemberSymbol != null && (int)node.MemberSymbol.Kind == 6)
{
_sourceAssembly.NoteFieldAccess((FieldSymbol)node.MemberSymbol.OriginalDefinition, read: false, write: true);
}
return result;
}
public override BoundNode VisitDynamicObjectInitializerMember(BoundDynamicObjectInitializerMember node)
{
return null;
}
protected override void VisitAssignmentOfNullCoalescingAssignment(BoundNullCoalescingAssignmentOperator node, BoundPropertyAccess propertyAccessOpt)
{
base.VisitAssignmentOfNullCoalescingAssignment(node, propertyAccessOpt);
Assign(node.LeftOperand, node.RightOperand);
}
protected override void AdjustStateForNullCoalescingAssignmentNonNullCase(BoundNullCoalescingAssignmentOperator node)
{
Assign(node.LeftOperand, node.LeftOperand);
}
protected override void AfterVisitInlineArrayAccess(BoundInlineArrayAccess node)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
if ((int)node.GetItemOrSliceHelper == 402)
{
NoteWrite(node.Expression, null, read: false);
}
}
protected override void AfterVisitConversion(BoundConversion node)
{
if (node.Conversion.IsInlineArray && node.Type.OriginalDefinition.Equals(compilation.GetWellKnownType((WellKnownType)275), (TypeCompareKind)63))
{
NoteWrite(node.Operand, null, read: false);
}
}
protected override string Dump(LocalState state)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("[assigned ");
AppendBitNames(state.Assigned, stringBuilder);
stringBuilder.Append("]");
return stringBuilder.ToString();
}
protected void AppendBitNames(BitVector a, StringBuilder builder)
{
bool flag = false;
foreach (int item in ((BitVector)(ref a)).TrueBits())
{
if (flag)
{
builder.Append(", ");
}
flag = true;
AppendBitName(item, builder);
}
}
protected void AppendBitName(int bit, StringBuilder builder)
{
LocalDataFlowPass<LocalState, LocalFunctionState>.VariableIdentifier variableIdentifier = variableBySlot[bit];
if (variableIdentifier.ContainingSlot > 0)
{
AppendBitName(variableIdentifier.ContainingSlot, builder);
builder.Append(".");
}
builder.Append((bit == 0) ? "<unreachable>" : (string.IsNullOrEmpty(variableIdentifier.Symbol.Name) ? ("<anon>" + variableIdentifier.Symbol.GetHashCode()) : variableIdentifier.Symbol.Name));
}
protected override bool Meet(ref LocalState self, ref LocalState other)
{
if (((BitVector)(ref self.Assigned)).Capacity != ((BitVector)(ref other.Assigned)).Capacity)
{
Normalize(ref self);
Normalize(ref other);
}
if (!other.Reachable)
{
((BitVector)(ref self.Assigned))[0] = true;
return true;
}
bool result = false;
for (int i = 1; i < ((BitVector)(ref self.Assigned)).Capacity; i++)
{
if (((BitVector)(ref other.Assigned))[i] && !((BitVector)(ref self.Assigned))[i])
{
SetSlotAssigned(i, ref self);
result = true;
}
}
return result;
}
protected override bool Join(ref LocalState self, ref LocalState other)
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
if (self.Reachable == other.Reachable)
{
if (((BitVector)(ref self.Assigned)).Capacity != ((BitVector)(ref other.Assigned)).Capacity)
{
Normalize(ref self);
Normalize(ref other);
}
return ((BitVector)(ref self.Assigned)).IntersectWith(ref other.Assigned);
}
if (!self.Reachable)
{
self.Assigned = ((BitVector)(ref other.Assigned)).Clone();
return true;
}
return false;
}
protected override LocalFunctionState CreateLocalFunctionState(LocalFunctionSymbol symbol)
{
return CreateLocalFunctionState();
}
private LocalFunctionState CreateLocalFunctionState()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return new LocalFunctionState(new LocalState(BitVector.AllSet(variableBySlot.Count), normalizeToBottom: true), UnreachableState());
}
protected override void VisitLocalFunctionUse(LocalFunctionSymbol localFunc, LocalFunctionState localFunctionState, SyntaxNode syntax, bool isCall)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
((HashSet<LocalFunctionSymbol>)(object)_usedLocalFunctions).Add(localFunc);
BitVector readVars = localFunctionState.ReadVars;
for (int i = 1; i < ((BitVector)(ref readVars)).Capacity; i++)
{
if (((BitVector)(ref readVars))[i])
{
Symbol symbol = variableBySlot[i].Symbol;
CheckIfAssignedDuringLocalFunctionReplay(symbol, syntax, i);
}
}
base.VisitLocalFunctionUse(localFunc, localFunctionState, syntax, isCall);
}
private void CheckIfAssignedDuringLocalFunctionReplay(Symbol symbol, SyntaxNode node, int slot)
{
if ((object)symbol == null)
{
return;
}
NoteRead(symbol);
if (State.Reachable)
{
if (slot >= ((BitVector)(ref State.Assigned)).Capacity)
{
Normalize(ref State);
}
if (slot > 0 && !State.IsAssigned(slot))
{
ReportUnassignedIfNotCapturedInLocalFunction(symbol, node, slot, skipIfUseBeforeDeclaration: false);
}
}
}
private void RecordReadInLocalFunction(int slot)
{
LocalFunctionSymbol nearestLocalFunctionOpt = GetNearestLocalFunctionOpt(CurrentSymbol);
LocalFunctionState orCreateLocalFuncUsages = GetOrCreateLocalFuncUsages(nearestLocalFunctionOpt);
TypeSymbol type = variableBySlot[slot].Symbol.GetTypeOrReturnType().Type;
if (EmptyStructTypeCache.IsTrackableStructType(type))
{
foreach (FieldSymbol structInstanceField in _emptyStructTypeCache.GetStructInstanceFields(type))
{
int orCreateSlot = GetOrCreateSlot(structInstanceField, slot);
if (orCreateSlot > 0 && !State.IsAssigned(orCreateSlot))
{
RecordReadInLocalFunction(orCreateSlot);
}
}
return;
}
((BitVector)(ref orCreateLocalFuncUsages.ReadVars))[slot] = true;
}
private BitVector GetCapturedBitmask()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
int count = variableBySlot.Count;
BitVector result = BitVector.AllSet(count);
for (int i = 1; i < count; i++)
{
((BitVector)(ref result))[i] = IsCapturedInLocalFunction(i);
}
return result;
}
private bool IsCapturedInLocalFunction(int slot)
{
if (slot <= 0)
{
return false;
}
Symbol symbol = variableBySlot[RootSlot(slot)].Symbol;
LocalFunctionSymbol nearestLocalFunctionOpt = GetNearestLocalFunctionOpt(CurrentSymbol);
if ((object)nearestLocalFunctionOpt != null)
{
return Symbol.IsCaptured(symbol, nearestLocalFunctionOpt);
}
return false;
}
private static LocalFunctionSymbol GetNearestLocalFunctionOpt(Symbol symbol)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Invalid comparison between Unknown and I4
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Invalid comparison between Unknown and I4
while (symbol != null)
{
if ((int)symbol.Kind == 9 && (int)((MethodSymbol)symbol).MethodKind == 17)
{
return (LocalFunctionSymbol)symbol;
}
symbol = symbol.ContainingSymbol;
}
return null;
}
protected override LocalFunctionState LocalFunctionStart(LocalFunctionState startState)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
LocalFunctionState localFunctionState = CreateLocalFunctionState();
localFunctionState.ReadVars = ((BitVector)(ref startState.ReadVars)).Clone();
((BitVector)(ref startState.ReadVars)).Clear();
return localFunctionState;
}
protected override bool LocalFunctionEnd(LocalFunctionState savedState, LocalFunctionState currentState, ref LocalState stateAtReturn)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
if (((BitVector)(ref currentState.CapturedMask)).IsNull)
{
currentState.CapturedMask = GetCapturedBitmask();
currentState.InvertedCapturedMask = ((BitVector)(ref currentState.CapturedMask)).Clone();
((BitVector)(ref currentState.InvertedCapturedMask)).Invert();
}
((BitVector)(ref stateAtReturn.Assigned)).IntersectWith(ref currentState.CapturedMask);
if (NonMonotonicState.HasValue)
{
LocalState value = NonMonotonicState.Value;
((BitVector)(ref value.Assigned)).UnionWith(ref currentState.InvertedCapturedMask);
NonMonotonicState = Optional<LocalState>.op_Implicit(value);
}
BitVector readVars = currentState.ReadVars;
((BitVector)(ref readVars)).IntersectWith(ref currentState.CapturedMask);
return ((BitVector)(ref savedState.ReadVars)).UnionWith(ref readVars);
}
}