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

Add clang-tidy check to catch incorrect use of RNGs #39576

Merged
merged 4 commits into from
Apr 15, 2020

Conversation

jbytheway
Copy link
Contributor

Summary

SUMMARY: Infrastructure "Add clang-tidy check to catch incorrect use of RNGs"

Purpose of change

We try to control how randomness enters the game. Primarily this is to permit test failures to be reproducible. Ideally we want the same tests run with the same seed to be identical on every platform.

We haven't achieved that yet, but one thing we need to ensure is that when we're deliberately introducing randomness to the game, we do it in a controlled fashion.

Over the past couple of years we migrated all the randomness to the standardized functions in rng.h. However, those who are unaware of the constraints are liable to accidentally misuse randomness in ways that are problematic.

We need a way to automatically enforce this convention in CI.

Describe the solution

Add a clang-tidy check. It looks for:

  • Any use of the C/POSIX standard random function (rand() and its friends).
  • Any construction of a C++ <random> engine. In most cases, code should use the existing engine, not construct its own.

There are a few exceptions, where I have added suppressions for the check.

The other examples I have refactored to use the rng.h facilities.

Testing

Running clang-tidy and the unit tests.

Additional context

The last major hurdle I'm aware of to portably reproducible tests is the order in which the tests are run. The next step is to switch the tests to --order rand so that our consistent RNG can also control the test order (rather than relying on the linker). But we need the tests to work more reliably when run in a random order before we can do that.

cur_npc is null exactly when stationed_npcs is empty.  Writing it this
way makes clang-tidy happier.
Various places in the codebase were not using the standard randomness as
intended, which might lead to non-reproducible test failures.

Rewrite them to do so.  Throw in a litle refactoring at the same time.
We need to ensure that all use of random number generators uses the
common tools in rng.h in order to get reproducible test results.  Add a
clang-tidy check for misuses.
@@ -1838,7 +1838,7 @@ void basecamp::job_assignment_ui()
selection--;
}
} else if( action == "CONFIRM" ) {
if( !stationed_npcs.empty() ) {
if( cur_npc ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Forgot to mention in the original description: this fix is for an unrelated null pointer dereference warning that clang-tidy also gave me while working on this PR.

@kevingranade kevingranade merged commit 7e79360 into CleverRaven:master Apr 15, 2020
@jbytheway jbytheway mentioned this pull request Apr 15, 2020
@jbytheway jbytheway deleted the detect_bad_rng_seeding branch April 15, 2020 10:22
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.

2 participants