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: Unreachable code query #17525

Merged
merged 18 commits into from
Oct 10, 2024
Merged

Rust: Unreachable code query #17525

merged 18 commits into from
Oct 10, 2024

Conversation

geoffw0
Copy link
Contributor

@geoffw0 geoffw0 commented Sep 19, 2024

Unreachable code query for Rust.

@paldepind please would you review, particularly whether the logic in firstUnreachable and skipNode is reasonable and written as cleanly as possible right now; and whether there are obvious explanations for the false positive results in the test?

@geoffw0 geoffw0 added no-change-note-required This PR does not need a change note Rust Pull requests that update Rust code labels Sep 19, 2024
Copy link
Contributor

QHelp previews:

rust/ql/src/queries/unusedentities/UnreachableCode.qhelp

Unreachable code

This rule finds code that is never reached. Unused code should be removed to increase readability and avoid confusion.

Recommendation

Remove any unreachable code.

Example

In the following example, the final return statement can never be reached:

fn fib(input: u32) -> u32 {
	if (input == 0) {
		return 0;
	} else if (input == 1) {
		return 1;
	} else {
		return fib(input - 1) + fib(input - 2);
	}

	return input; // BAD: this code is never reached
}

The problem can be fixed simply by removing the unreachable code:

fn fib(input: u32) -> u32 {
	if (input == 0) {
		return 0;
	} else if (input == 1) {
		return 1;
	} else {
		return fib(input - 1) + fib(input - 2);
	}
}

References

@geoffw0 geoffw0 added the ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. label Sep 20, 2024
subatoi
subatoi previously approved these changes Sep 23, 2024
Copy link
Contributor

@subatoi subatoi left a comment

Choose a reason for hiding this comment

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

👍 LGTM

aibaars
aibaars previously approved these changes Sep 27, 2024
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.

This looks fine to me. However, it may be worth fixing some of the missing CFG steps instead of marking a lot of false results in the expected output. By the looks of it they are mainly caused by the lack of special handling of boolean literals. I updated the branch to pull in the latest CFG improvements, with a bit of luck some of the issues have already been fixed.

@aibaars
Copy link
Contributor

aibaars commented Sep 27, 2024

@hvitved Could you have a quick look at this too?

@geoffw0 geoffw0 dismissed stale reviews from aibaars and subatoi via 9e3f4cd October 8, 2024 10:43
* Holds if `n` is an AST node that's unreachable.
*/
private predicate unreachable(AstNode n) {
not n = any(CfgNode cfn).getAstNode()
Copy link
Contributor

Choose a reason for hiding this comment

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

We also need to restrict this to nodes that can possibly be part of a CFG, for example ParenExprs cannot. I think the best heuristic is simply n instanceof ControlFlowTree.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

n instanceof ControlFlowGraphImpl::ControlFlowTree doesn't work ... unless this fix requires more of your work-in-progress to apply?

Copy link
Contributor

Choose a reason for hiding this comment

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

Right. Try with

  exists(ControlFlowGraphImpl::ControlFlowTree cft |
    cft.succ(n, _, _)
    or
    cft.succ(_, n, _)
  )

instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, that works perfectly and I can see what the intent is now.

I've updated the PR.

hvitved
hvitved previously approved these changes Oct 9, 2024
@geoffw0 geoffw0 merged commit 09c2f90 into github:main Oct 10, 2024
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation no-change-note-required This PR does not need a change note ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. Rust Pull requests that update Rust code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants