private bool IsTrackedLocation(AbstractLocation location) { return(CurrentAnalysisData.ContainsKey(location) || location.SymbolOpt is IParameterSymbol parameter && parameter.Type.IsReferenceType && Equals(parameter.ContainingSymbol, GetBottomOfStackOwningSymbol())); ISymbol GetBottomOfStackOwningSymbol() { if (DataFlowAnalysisContext.InterproceduralAnalysisDataOpt == null) { return(OwningSymbol); } return(DataFlowAnalysisContext.InterproceduralAnalysisDataOpt.MethodsBeingAnalyzed .Single(m => m.InterproceduralAnalysisDataOpt == null) .OwningSymbol); } }
public override DisposeAbstractValue VisitFieldReference(IFieldReferenceOperation operation, object argument) { var value = base.VisitFieldReference(operation, argument); if (_trackedInstanceFieldLocationsOpt != null && !operation.Field.IsStatic && operation.Instance?.Kind == OperationKind.InstanceReference) { var pointsToAbstractValue = GetPointsToAbstractValue(operation); if (pointsToAbstractValue.Kind == PointsToAbstractValueKind.KnownLocations && pointsToAbstractValue.Locations.Count == 1) { var location = pointsToAbstractValue.Locations.Single(); if (location.IsAnalysisEntityDefaultLocation) { if (!_trackedInstanceFieldLocationsOpt.TryGetValue(operation.Field, out _)) { // First field reference on any control flow path. // Create a default instance to represent the object referenced by the field at start of the method and // check if the instance has NotDisposed state, indicating it is a disposable field that must be tracked. if (HandleInstanceCreation(operation, pointsToAbstractValue, defaultValue: DisposeAbstractValue.NotDisposable) == DisposeAbstractValue.NotDisposed) { _trackedInstanceFieldLocationsOpt.Add(operation.Field, pointsToAbstractValue); } } else if (!CurrentAnalysisData.ContainsKey(location)) { // This field has already started being tracked on a different control flow path. // Process the default instance creation on this control flow path as well. var disposedState = HandleInstanceCreation(operation, pointsToAbstractValue, DisposeAbstractValue.NotDisposable); Debug.Assert(disposedState == DisposeAbstractValue.NotDisposed); } } } } return(value); }
protected override bool HasAbstractValue(AnalysisEntity analysisEntity) => CurrentAnalysisData.ContainsKey(analysisEntity);