Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix S1854 FP: Throw should connect to outer catch #9528

Merged
merged 2 commits into from
Jul 18, 2024

Conversation

mary-georgiou-sonarsource
Copy link
Contributor

Fixes #9468

@@ -138,6 +138,10 @@ private void BuildBranches(BasicBlock block)
AddPredecessorsOutsideRegion(finallyBlock);
}
}
if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.FirstOrDefault(x => x.Semantics == ControlFlowBranchSemantics.Rethrow) is { })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.FirstOrDefault(x => x.Semantics == ControlFlowBranchSemantics.Rethrow) is { })
if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.FirstOrDefault(x => x.Semantics == ControlFlowBranchSemantics.Rethrow) is not null)

It's probably an FN for T0007.

Copy link
Contributor

@sebastien-marichal sebastien-marichal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!
We discussed it together and it seems good for me.
I only added a comment about is not null usage

Copy link
Contributor

@Tim-Pohlmann Tim-Pohlmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM only cosmetic suggestions.

{
var tryRegion = block.EnclosingRegion(ControlFlowRegionKind.TryAndCatch).NestedRegion(ControlFlowRegionKind.Try);
foreach (var catchBlock in tryRegion.ReachableHandlers()
.Where(x => x.Kind == ControlFlowRegionKind.Catch && x != block.EnclosingRegion && x.FirstBlockOrdinal > block.Ordinal)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.Where(x => x.Kind == ControlFlowRegionKind.Catch && x != block.EnclosingRegion && x.FirstBlockOrdinal > block.Ordinal)
.Where(x => x.Kind == ControlFlowRegionKind.Catch && x.FirstBlockOrdinal > block.Ordinal)

The middle condition is already covered by the last condition.

Comment on lines 171 to 173
foreach (var catchBlock in tryRegion.ReachableHandlers()
.Where(x => x.Kind == ControlFlowRegionKind.Catch && x != block.EnclosingRegion && x.FirstBlockOrdinal > block.Ordinal)
.SelectMany(x => x.Blocks(Cfg)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would separate this into an extra variable. foreach with multiple lines is always awkward to read.

{
var code = """
var value = 100;
try{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting

@@ -138,6 +138,10 @@ private void BuildBranches(BasicBlock block)
AddPredecessorsOutsideRegion(finallyBlock);
}
}
if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.FirstOrDefault(x => x.Semantics == ControlFlowBranchSemantics.Rethrow) is { })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.FirstOrDefault(x => x.Semantics == ControlFlowBranchSemantics.Rethrow) is { })
if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.Any(x => x.Semantics == ControlFlowBranchSemantics.Rethrow))

Copy link

sonarcloud bot commented Jul 18, 2024

Copy link

sonarcloud bot commented Jul 18, 2024

@mary-georgiou-sonarsource mary-georgiou-sonarsource merged commit a9af306 into master Jul 18, 2024
17 checks passed
@mary-georgiou-sonarsource mary-georgiou-sonarsource deleted the mary/lva-connect-throw branch July 18, 2024 14:57
@@ -138,6 +138,10 @@ private void BuildBranches(BasicBlock block)
AddPredecessorsOutsideRegion(finallyBlock);
}
}
if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.Any(x => x.Semantics == ControlFlowBranchSemantics.Rethrow))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about Throw semantics? All the UTs have throw, but throw new Excetion("Whaaat?", ex) should behave the same

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed here #9530
Thanks @sebastien-marichal

@@ -161,6 +165,15 @@ private void BuildBranchesFinally(BasicBlock source, ControlFlowRegion finallyRe
}
}

private void BuildBranchesNestedCatchRethrow(BasicBlock block)
{
var reachableHandlers = block.EnclosingRegion(ControlFlowRegionKind.TryAndCatch).NestedRegion(ControlFlowRegionKind.Try).ReachableHandlers();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't ReachableHandlers also connect back to it's own Catch in this case? Or more precisely, all neighboring catches too? That would be wrong

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pavel-mikula-sonarsource I'm after asking for x.FirstBlockOrdinal > block.Ordinal) - all the catch with greater ordinal that the one I'm in.
Isn't that working?

var reachableHandlers = block.EnclosingRegion(ControlFlowRegionKind.TryAndCatch).NestedRegion(ControlFlowRegionKind.Try).ReachableHandlers();
foreach (var catchBlock in reachableHandlers.Where(x => x.Kind == ControlFlowRegionKind.Catch && x.FirstBlockOrdinal > block.Ordinal).SelectMany(x => x.Blocks(Cfg)))
{}

Also not sure what you mean neighbouring catches :/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try
Catch Ex As IOException
  Throw 'You are here, with your block.Ordinal
Catch Ex As FormatException
   'This is a neighbour that you don't want to connect to. And it has FirstBlockOrdinal > block.Ordinal
End Try

Copy link
Contributor

@pavel-mikula-sonarsource pavel-mikula-sonarsource Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go escape, you'd need to store your TryAndCatch region, and be bigger than its LastBlockOrdinal

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got It!
I'm opening a PR to fix this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix S1854 FP: Throw should connect to outer catch
4 participants