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

clang-tidy: Enable more checks #149

Closed
wants to merge 7 commits into from
Closed

Conversation

psalz
Copy link
Member

@psalz psalz commented Sep 27, 2022

So far we've used clang-tidy only to enforce naming conventions. This PR enables a whole set of additional checks as suggested in #127.

Notably this includes misc-const-correctness, a check that was recently added in clang-tidy 15. While we don't yet use clang-tidy 15 in CI, this patch includes a (semi-automatic) fixup pass that was done for all const-correctness violations found through that check. Unfortunately the check seems to be a little buggy still (producing false positives in certain situations) which is why I've decided to not turn it into an error for now.

Here's a summary of the remaining clang-tidy warnings we produce with the set of checks enabled in this patch:

Found 465 diagnostics (out of 2880 parsed; 2415 were duplicates).
   96: readability-qualified-auto
   51: readability-function-cognitive-complexity
   46: bugprone-unchecked-optional-access
   33: cppcoreguidelines-special-member-functions
   21: cppcoreguidelines-init-variables
   18: readability-implicit-bool-conversion
   16: bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions
   16: readability-named-parameter
   15: performance-unnecessary-value-param
   14: cppcoreguidelines-avoid-non-const-global-variables
   13: cppcoreguidelines-pro-bounds-constant-array-index
   12: clang-analyzer-deadcode.DeadStores
   12: cppcoreguidelines-pro-bounds-array-to-pointer-decay
   11: readability-isolate-declaration
   10: cppcoreguidelines-pro-type-member-init
    9: cppcoreguidelines-pro-type-static-cast-downcast
    8: bugprone-exception-escape
    6: cppcoreguidelines-pro-type-vararg
    6: readability-else-after-return
    6: cppcoreguidelines-non-private-member-variables-in-classes
    5: cppcoreguidelines-pro-type-reinterpret-cast
    4: readability-redundant-access-specifiers
    3: performance-faster-string-find
    3: cppcoreguidelines-pro-type-const-cast
    3: cppcoreguidelines-owning-memory
    3: clang-diagnostic-error
    2: bugprone-implicit-widening-of-multiplication-result
    2: bugprone-reserved-identifier
    2: readability-inconsistent-declaration-parameter-name
    2: misc-const-correctness
    2: readability-static-accessed-through-instance
    2: performance-noexcept-move-constructor
    2: clang-analyzer-optin.mpi.MPI-Checker
    2: cppcoreguidelines-prefer-member-initializer
    2: readability-convert-member-functions-to-static
    1: readability-redundant-smartptr-get
    1: readability-suspicious-call-argument
    1: clang-analyzer-core.NonNullParamChecker
    1: performance-move-const-arg
    1: performance-for-range-copy
    1: clang-analyzer-core.CallAndMessage
    1: readability-make-member-function-const

Remember that our CI setup only runs checks on diffs, so I think it is reasonable to address these whenever we touch those respective parts of the code.

Resolves #127.

@psalz psalz changed the title clang-tidy: Require _m prefix for protected members as well clang-tidy: Enable more checks Sep 27, 2022
Clang-tidy 15 includes a new check "misc-const-correctness", which marks
locations where local variables could be qualified as const.
Unfortunately the check does not seem to be robust enough yet to be
enabled as an error (i.e., it includes some false positives).
For the time being it is also not checked during CI, as the CI
containers currently use Clang 14.

Nevertheless, a `clang-tidy --fix` pass has been applied to update many
locations to be qualified as const. A workaround has been added to
disable the diagnostic on several types (`buffer`, `accessor`,
`host_object`, `side_effect`) that could be marked const in most
situations, but shouldn't be from a semantic perspective.

Additionally, the clang-format configuration now prescribes the position
of CV-qualifiers to be to the left of types (i.e., "west-const") through
an option that was introduced with Clang 14.
This does not include any fixes as most of the remaining warnings either
require some thought to fix or can simply be handled the next time that
part of the code is touched.
@psalz psalz force-pushed the enable-more-clang-tidy-rules branch from da7cea0 to 1a57677 Compare September 27, 2022 10:19
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 25 out of 55. Check the log or trigger a new build to see more.

examples/distr_io/distr_io.cc Show resolved Hide resolved
examples/syncing/syncing.cc Show resolved Hide resolved
include/accessor.h Show resolved Hide resolved
include/accessor.h Show resolved Hide resolved
include/handler.h Show resolved Hide resolved
src/user_bench.cc Show resolved Hide resolved
src/user_bench.cc Show resolved Hide resolved
src/user_bench.cc Show resolved Hide resolved
test/accessor_tests.cc Show resolved Hide resolved
test/accessor_tests.cc Show resolved Hide resolved
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 25 out of 30. Check the log or trigger a new build to see more.

test/accessor_tests.cc Show resolved Hide resolved
test/buffer_manager_tests.cc Show resolved Hide resolved
test/device_selection_tests.cc Show resolved Hide resolved
test/runtime_tests.cc Show resolved Hide resolved
test/runtime_tests.cc Show resolved Hide resolved
test/runtime_tests.cc Show resolved Hide resolved
test/runtime_tests.cc Show resolved Hide resolved
test/runtime_tests.cc Show resolved Hide resolved
test/runtime_tests.cc Show resolved Hide resolved
test/runtime_tests.cc Show resolved Hide resolved
@psalz
Copy link
Member Author

psalz commented Sep 27, 2022

Turns out I was missing two commas in the list of checks...

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

buf_a.get_access<access_mode::discard_write>(cgh, fixed<1>({64, 64}));
});
task_id tid_3 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
const task_id tid_3 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {

Choose a reason for hiding this comment

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

warning: Value stored to 'tid_3' during its initialization is never read [clang-analyzer-deadcode.DeadStores]

		const task_id tid_3 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
                ^

test/task_graph_tests.cc:393: Value stored to 'tid_3' during its initialization is never read

		const task_id tid_3 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
                ^

buf_a.get_access<access_mode::read_write>(cgh, fixed<1>({32, 64}));
});

auto horizon = task_manager_testspy::get_current_horizon(tm);
CHECK(task_manager_testspy::get_num_horizons(tm) == 1);
CHECK(horizon.has_value());

task_id tid_6 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
const task_id tid_6 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {

Choose a reason for hiding this comment

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

warning: Value stored to 'tid_6' during its initialization is never read [clang-analyzer-deadcode.DeadStores]

		const task_id tid_6 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
                ^

test/task_graph_tests.cc:404: Value stored to 'tid_6' during its initialization is never read

		const task_id tid_6 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
                ^

buf_b.get_access<access_mode::read_write>(cgh, fixed<1>({0, 128}));
});
task_id tid_7 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
const task_id tid_7 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {

Choose a reason for hiding this comment

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

warning: Value stored to 'tid_7' during its initialization is never read [clang-analyzer-deadcode.DeadStores]

		const task_id tid_7 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
                ^

test/task_graph_tests.cc:407: Value stored to 'tid_7' during its initialization is never read

		const task_id tid_7 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
                ^

@@ -417,7 +417,7 @@
CHECK(region_map_a.get_region_values(make_region(32, 96)).front().second.value() == tid_4);
}

task_id tid_8 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
const task_id tid_8 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {

Choose a reason for hiding this comment

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

warning: Value stored to 'tid_8' during its initialization is never read [clang-analyzer-deadcode.DeadStores]

		const task_id tid_8 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
                ^

test/task_graph_tests.cc:419: Value stored to 'tid_8' during its initialization is never read

		const task_id tid_8 = test_utils::add_host_task(tm, on_master_node, [&](handler& cgh) {
                ^

Copy link
Contributor

@fknorr fknorr left a comment

Choose a reason for hiding this comment

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

Nice cleanup! A couple of notes though, mostly about autofixes.

##########################
# Various check options
##########################
- key: misc-const-correctness.TransformPointersAsValues
Copy link
Contributor

Choose a reason for hiding this comment

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

From the documentation, the warning on pointers should be enabled with WarnPointersAsValues before enabling just the fixit hints with TransformPointersAsValues. Not sure if this is technically required since we are obviously receiving warnings already.

Comment on lines +413 to +417
// The ComputeCpp legacy compiler seems to think that these can throw
#if CELERITY_DETAIL_IS_OLD_COMPUTECPP_COMPILER
accessor(accessor&&) = default;
accessor& operator=(accessor&&) = default;
#else
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this mean they can't be defaulted? Hm, probably fine as a hack for a compiler whose days are numbered.

@@ -221,17 +222,21 @@ class accessor<DataT, Dims, Mode, target::device> : public detail::accessor_base
friend struct detail::accessor_testspy;

public:
CELERITY_DETAIL_HACK_CLANG_TIDY_ALLOW_NON_CONST(accessor)
Copy link
Contributor

Choose a reason for hiding this comment

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

I know this macro was my idea, but maybe we can make the connection between the magic happening here and the explicitly-defaulted constructors more obvious.

  • Either by renaming it, e.g. CELERITY_DETAIL_HACK_DEFINE_COPY_CTOR_TO_ALLOW_CLANG_TIDY_NON_CONST (that's a mouthful)
  • Or by just substituting the macro invocations with the actual constructor plus a comment

What do you think?

@@ -221,17 +222,21 @@ class accessor<DataT, Dims, Mode, target::device> : public detail::accessor_base
friend struct detail::accessor_testspy;

public:
CELERITY_DETAIL_HACK_CLANG_TIDY_ALLOW_NON_CONST(accessor)
accessor(accessor&&) noexcept = default;
accessor& operator=(accessor&&) noexcept = default;
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider moving the move-assign definition closer to the copy-assign below (it is not related to the CLANG_TIDY_HACK)

@@ -594,6 +614,10 @@ class local_accessor {
using const_reference = const DataT&;
using size_type = size_t;

CELERITY_DETAIL_HACK_CLANG_TIDY_ALLOW_NON_CONST(local_accessor)
local_accessor(local_accessor&&) noexcept = default;
local_accessor& operator=(local_accessor&&) noexcept = default;
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe neither this move-assignment nor the existing copy-assignment definitions are actually needed.

@@ -312,7 +312,7 @@ TEST_CASE_METHOD(celerity::test_utils::mpi_fixture, "pick_device prints expected
mp_0.create_devices(dt::cpu);
mp_1.create_devices(dt::gpu, dt::gpu);

celerity::detail::device_config d_cfg{3, 0};
celerity::detail::device_config const d_cfg{3, 0};
Copy link
Contributor

Choose a reason for hiding this comment

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

Here's an east-const that got away.

@@ -325,7 +325,7 @@ TEST_CASE_METHOD(celerity::test_utils::mpi_fixture, "pick_device prints expected
mp_0.create_devices(dt::cpu);
mp_1.create_devices(dt::gpu, dt::gpu);

celerity::detail::device_config d_cfg{1, 5};
celerity::detail::device_config const d_cfg{1, 5};
Copy link
Contributor

Choose a reason for hiding this comment

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

Another east const.

@@ -104,7 +104,7 @@ static void test_access(sycl::queue& q, sycl::buffer<int, 1>& test_buf, const su
});
}).wait_and_throw();

sycl::host_accessor verify_acc{verify_buf};
sycl::host_accessor const verify_acc{verify_buf};
Copy link
Contributor

Choose a reason for hiding this comment

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

Another east-const.

@@ -231,7 +231,7 @@ namespace detail {
{
size_t relative = global_linear_id;
for(int nd = 0; nd < Dims; ++nd) {
int d = Dims - 1 - nd;
int const d = Dims - 1 - nd;
Copy link
Contributor

Choose a reason for hiding this comment

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

More east constness.

Comment on lines +30 to +34
// Clang-tidy doesn't like that Catch2's RAII helper for scoped INFO messages isn't qualified as `const`.
// TODO: Fix in Catch2
#undef INFO
#define INFO(msg) const INTERNAL_CATCH_INFO("INFO", msg)

Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a way to exclude vendor/* from clang-tidy checks?

@psalz psalz closed this Feb 20, 2023
@psalz psalz deleted the enable-more-clang-tidy-rules branch April 6, 2023 16:55
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.

Decide on which clang-tidy checks we want to enable
2 participants