Skip to content

Commit

Permalink
fix bug
Browse files Browse the repository at this point in the history
  • Loading branch information
mary-georgiou-sonarsource committed Jul 18, 2024
1 parent 0fb0f76 commit 61d4eb8
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace SonarAnalyzer.CFG.LiveVariableAnalysis;

public sealed class RoslynLiveVariableAnalysis : LiveVariableAnalysisBase<ControlFlowGraph, BasicBlock>
{
private readonly Dictionary<CaptureId, List<IOperation>> flowCaptureOperations = [];
private readonly Dictionary<CaptureId, List<ISymbol>> flowCaptureOperations = [];
private readonly Dictionary<int, List<BasicBlock>> blockPredecessors = [];
private readonly Dictionary<int, List<BasicBlock>> blockSuccessors = [];

Expand Down Expand Up @@ -86,24 +86,24 @@ private void ResolveCaptures()
.Select(x => x.Instance.ToFlowCapture()))
{
if (flowCapture.Value.AsFlowCaptureReference() is { } captureReference
&& flowCaptureOperations.TryGetValue(captureReference.Id, out var capturedOperations))
&& flowCaptureOperations.TryGetValue(captureReference.Id, out var symbols))
{
AppendFlowCaptureReference(flowCapture.Id, capturedOperations.ToArray());
AppendFlowCaptureReference(flowCapture.Id, symbols.ToArray());
}
else
else if (ParameterOrLocalSymbol(flowCapture.Value) is { } symbol)
{
AppendFlowCaptureReference(flowCapture.Id, flowCapture.Value);
AppendFlowCaptureReference(flowCapture.Id, symbol);
}
}

void AppendFlowCaptureReference(CaptureId id, params IOperation[] operations)
void AppendFlowCaptureReference(CaptureId id, params ISymbol[] symbols)
{
if (!flowCaptureOperations.TryGetValue(id, out var list))
{
list = [];
flowCaptureOperations.Add(id, list);
}
list.AddRange(operations);
list.AddRange(symbols);
}
}

Expand Down Expand Up @@ -223,17 +223,13 @@ private sealed class RoslynState : State
public RoslynState(RoslynLiveVariableAnalysis owner) =>
this.owner = owner;

public void ProcessBlock(ControlFlowGraph cfg, BasicBlock block, Dictionary<CaptureId, List<IOperation>> flowCaptureOperations)
public void ProcessBlock(ControlFlowGraph cfg, BasicBlock block, Dictionary<CaptureId, List<ISymbol>> flowCaptureOperations)
{
foreach (var operation in block.OperationsAndBranchValue.ToReversedExecutionOrder().Select(x => x.Instance))
{
if ((operation.AsFlowCapture() is { } flowCapture && flowCaptureOperations.TryGetValue(flowCapture.Id, out var captured))
|| (operation.AsFlowCaptureReference() is { } flowCaptureReference && flowCaptureOperations.TryGetValue(flowCaptureReference.Id, out captured)))
if (operation.AsFlowCaptureReference() is { } flowCaptureReference && flowCaptureOperations.TryGetValue(flowCaptureReference.Id, out var symbols))
{
foreach (var capturedOperation in captured)
{
ProcessOperation(cfg, capturedOperation);
}
UsedBeforeAssigned.UnionWith(symbols);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,9 @@ public void FlowCaptrure_NullCoalescingOperator_Overwrite()
var context = CreateContextCS(code, additionalParameters: "string s1");
context.ValidateEntry(LiveIn("s1"), LiveOut("s1"));
context.Validate(context.Cfg.Blocks[1], LiveIn("s1"));
context.Validate(context.Cfg.Blocks[2]); // This should have LiveIn("s1") and LiveOut("s1") but #1 gets as value all the assignment operation.
context.Validate(context.Cfg.Blocks[3], LiveOut("s1")); // This should have LiveIn("s1")
context.Validate(context.Cfg.Blocks[4], LiveOut("s1")); // This should have LiveIn("s1")
context.Validate(context.Cfg.Blocks[2], LiveOut("s1")); // This should have LiveIn("s1") and LiveOut("s1") but #1 gets as value all the assignment operation.
context.Validate(context.Cfg.Blocks[3], LiveIn("s1"), LiveOut("s1"));
context.Validate(context.Cfg.Blocks[4], LiveIn("s1"), LiveOut("s1"));
context.Validate(context.Cfg.Blocks[5], LiveIn("s1"));
context.ValidateExit();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ int LocalFunction(int arg)
var context = CreateContextCS(code, "LocalFunction");
context.ValidateEntry(LiveIn("arg"), LiveOut("arg"));
context.Validate("variable", LiveIn("arg"), LiveOut("arg"));
context.Validate("LocalFunction(arg - 1)", LiveIn("arg"), LiveOut("arg"));
context.Validate("0", LiveIn("arg"), LiveOut("arg"));
context.Validate("LocalFunction(arg - 1)", LiveIn("arg"));
context.Validate("0");
}

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1625,8 +1625,7 @@ public void NestedCatchAndRethrow()
// https://github.com/SonarSource/sonar-dotnet/issues/9471
void AssignmentInTernary(bool condition, string st)
{
string st2 = condition ? st = "Hi" : "Hello"; // Noncompliant FP
// ^^^^^^^^^
string st2 = condition ? st = "Hi" : "Hello"; // Compliant
Console.WriteLine(st);
Console.WriteLine(st2);
}
Expand All @@ -1635,7 +1634,7 @@ void AssignmentInTernary(bool condition, string st)
void AssignmentInSwitch()
{
char ch;
switch (ch = GetAChar()) // Noncompliant FP
switch (ch = GetAChar()) // Compliant
{
case 'A':
break;
Expand All @@ -1652,9 +1651,9 @@ void AssignmentInSwitch()
// https://github.com/SonarSource/sonar-dotnet/issues/9473
void ReassignAfterUsing(IDisposable data)
{
using (data = Something()) // Noncompliant
using (data = Something()) // Compliant - if Something() throws, value will be used directly in Console.WriteLine(data);
{
data = Something(); // Noncompliant FP
data = Something();
}
Console.WriteLine(data);

Expand Down

0 comments on commit 61d4eb8

Please sign in to comment.