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

Rust: More CFG modelling #17633

Merged
merged 15 commits into from
Oct 2, 2024
Merged

Rust: More CFG modelling #17633

merged 15 commits into from
Oct 2, 2024

Conversation

hvitved
Copy link
Contributor

@hvitved hvitved commented Oct 1, 2024

This PR fixes all CFG inconsistencies in our test suite, by adding missing cases to ControlFlowGraphImpl.qll.

Commit-by-commit review is suggested.

@github-actions github-actions bot added the Rust Pull requests that update Rust code label Oct 1, 2024
@hvitved hvitved marked this pull request as ready for review October 1, 2024 09:27
@@ -284,7 +284,9 @@ abstract class LoopingExprTree extends PostOrderTree {

abstract Label getLabel();

/** Whether this loop captures the `c` completion. */
abstract predicate entry(AstNode node);
Copy link
Contributor

Choose a reason for hiding this comment

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

A comment would be nice here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I still think a comment explaining the purpose of entry and how it differs from first would be nice.

Comment on lines +382 to +419
last(super.getPat(), pred, c) and
c.(MatchCompletion).failed() and
succ = this
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks a little weird. The pattern in a for-loop can never fail, it is actually the implicit iter.next() call that may return None and exit the loop. Not sure if it matters much though. Perhaps we should have a special IteratorCompletion here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it would be even better if we could desugar for loops.

@@ -86,7 +86,7 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion {
or
e = any(WhileExpr c).getCondition()
or
any(MatchArm arm).getGuard() = e
any(MatchGuard guard).getCondition() = e
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess we should drop /hideMatchGuard nodes from the AST at some point. They look like useless wrappers.

rust/ql/consistency-queries/CfgConsistency.ql Outdated Show resolved Hide resolved
@hvitved hvitved requested a review from aibaars October 1, 2024 19:49
/** Holds if `be` is the `else` branch of a `let` statement that results in a panic. */
private predicate letElsePanic(BlockExpr be) {
be = any(LetStmt let).getLetElse().getBlockExpr() and
exists(Completion c | CfgImpl::last(be, _, c) | completionIsNormal(c))
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks fine for now, we don't really have a way to identify "panic"-like statements. A real panic wouldn't complete normally, it would abort the program. When we extract types, we may refine this to hold if the type of the expression is !.


/** Holds if this block captures the break completion `c`. */
private predicate capturesBreakCompletion(LoopJumpCompletion c) {
c.isBreak() and
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you also handle shadowing of labels? It's a silly thing to do, and the rust compiler will warn about it, but shadowed labels are allowed. For example:

        'a: loop {
            'a: loop {
                'a: {
                    break 'a;
                }
                break 'a;
            }
            break 'a;
        }

You might want to add a test case, if you don't already have one;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, wait, I we don't have one that shadows; I'll add.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added one now, and the CFG is correct:

flowchart TD
1["enter test_loop_label_shadowing"]
10["b"]
11["ContinueExpr"]
12["ExprStmt"]
13["ContinueExpr"]
14["ExprStmt"]
2["1"]
3["ExprStmt"]
4["ExprStmt"]
5["IfExpr"]
6["b"]
7["ContinueExpr"]
8["ExprStmt"]
9["IfExpr"]

1 --> 3
2 --> 4
3 --> 2
4 --> 6
5 --> 14
6 -- false --> 10
6 -- true --> 8
7 -- continue --> 4
8 --> 7
9 --> 5
10 -- false --> 9
10 -- true --> 12
11 -- continue('loop) --> 4
12 --> 11
13 -- continue('loop) --> 4
14 --> 13
Loading

@@ -284,7 +284,9 @@ abstract class LoopingExprTree extends PostOrderTree {

abstract Label getLabel();

/** Whether this loop captures the `c` completion. */
abstract predicate entry(AstNode node);
Copy link
Contributor

Choose a reason for hiding this comment

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

I still think a comment explaining the purpose of entry and how it differs from first would be nice.

Copy link
Contributor

@aibaars aibaars left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@hvitved hvitved merged commit 3fa52ad into github:main Oct 2, 2024
14 checks passed
@hvitved hvitved deleted the rust/cfg-fixes branch October 2, 2024 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Rust Pull requests that update Rust code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants