public PointsToAnalysisData MergeAnalysisDataForBackEdge(PointsToAnalysisData forwardEdgeAnalysisData, PointsToAnalysisData backEdgeAnalysisData, Func <PointsToAbstractValue, IEnumerable <AnalysisEntity> > getChildAnalysisEntities)
        {
            Debug.Assert(forwardEdgeAnalysisData != null);
            Debug.Assert(backEdgeAnalysisData != null);

            // Stop tracking points to values present in both branches if their is an assignment to a may-be null value from the back edge.
            // Clone the input forwardEdgeAnalysisData to ensure we don't overwrite the input dictionary.
            forwardEdgeAnalysisData = new Dictionary <AnalysisEntity, PointsToAbstractValue>(forwardEdgeAnalysisData);
            List <AnalysisEntity> keysInMap1 = forwardEdgeAnalysisData.Keys.ToList();

            foreach (var key in keysInMap1)
            {
                var forwardEdgeValue = forwardEdgeAnalysisData[key];
                if (backEdgeAnalysisData.TryGetValue(key, out var backEdgeValue) &&
                    backEdgeValue != forwardEdgeValue)
                {
                    switch (backEdgeValue.NullState)
                    {
                    case NullAbstractValue.MaybeNull:
                        StopTrackingAnalysisDataForKey();
                        break;

                    case NullAbstractValue.NotNull:
                        if (backEdgeValue.MakeMayBeNull() != forwardEdgeAnalysisData[key])
                        {
                            StopTrackingAnalysisDataForKey();
                        }
                        break;
                    }

                    void StopTrackingAnalysisDataForKey()
                    {
                        var childEntities = getChildAnalysisEntities(forwardEdgeValue)
                                            .Union(getChildAnalysisEntities(backEdgeValue));

                        foreach (var childEntity in childEntities)
                        {
                            forwardEdgeAnalysisData[childEntity] = PointsToAbstractValue.Unknown;
                        }

                        forwardEdgeAnalysisData[key] = PointsToAbstractValue.Unknown;
                    }
                }
            }

            var resultMap = Merge(forwardEdgeAnalysisData, backEdgeAnalysisData);

            Debug.Assert(Compare(forwardEdgeAnalysisData, resultMap) <= 0);
            Debug.Assert(Compare(backEdgeAnalysisData, resultMap) <= 0);
            return(resultMap);
        }
Example #2
0
        public PointsToAnalysisData MergeAnalysisDataForBackEdge(PointsToAnalysisData map1, PointsToAnalysisData map2)
        {
            // Stop tracking points to values present in both branches.
            List <AnalysisEntity> keysInMap1 = map1.Keys.ToList();

            foreach (var key in keysInMap1)
            {
                if (map2.TryGetValue(key, out var value2) &&
                    value2 != map1[key])
                {
                    map1[key] = PointsToAbstractValue.Unknown;
                }
            }

            return(Merge(map1, map2));
        }