|
6 | 6 | using System.Diagnostics; |
7 | 7 | using System.Diagnostics.CodeAnalysis; |
8 | 8 | using System.Linq; |
| 9 | +using Analyzer.Utilities.PooledObjects; |
9 | 10 |
|
10 | 11 | namespace Microsoft.CodeAnalysis.FlowAnalysis.DataFlow |
11 | 12 | { |
@@ -170,6 +171,11 @@ private void ClearOverlappingAnalysisDataForIndexedEntity(AnalysisEntity analysi |
170 | 171 | return; |
171 | 172 | } |
172 | 173 |
|
| 174 | + // Collect all the overlapping indexed entities whose value needs to be updated into a builder. |
| 175 | + // Ensure that we perform these state updates after the foreach loop to avoid modifying the |
| 176 | + // underlying CoreAnalysisData within the loop. |
| 177 | + // See https://github.com/dotnet/roslyn-analyzers/issues/6929 for more details. |
| 178 | + using var builder = ArrayBuilder<(AnalysisEntity, TValue)>.GetInstance(CoreAnalysisData.Count); |
173 | 179 | foreach (var entity in CoreAnalysisData.Keys) |
174 | 180 | { |
175 | 181 | if (entity.Indices.Length != analysisEntity.Indices.Length || |
@@ -197,10 +203,15 @@ private void ClearOverlappingAnalysisDataForIndexedEntity(AnalysisEntity analysi |
197 | 203 | var mergedValue = ValueDomain.Merge(value, existingValue); |
198 | 204 | if (!existingValue!.Equals(mergedValue)) |
199 | 205 | { |
200 | | - SetAbstractValue(entity, mergedValue); |
| 206 | + builder.Add((entity, mergedValue)); |
201 | 207 | } |
202 | 208 | } |
203 | 209 | } |
| 210 | + |
| 211 | + foreach (var (entity, newValue) in builder.AsEnumerable()) |
| 212 | + { |
| 213 | + SetAbstractValue(entity, newValue); |
| 214 | + } |
204 | 215 | } |
205 | 216 |
|
206 | 217 | protected override void Dispose(bool disposing) |
|
0 commit comments