-
Notifications
You must be signed in to change notification settings - Fork 15
Introduce clang-tidy #920
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
base: master
Are you sure you want to change the base?
Introduce clang-tidy #920
Conversation
e130e75
to
d114491
Compare
Signed-off-by: Philipp Jungkamp <[email protected]>
Signed-off-by: Philipp Jungkamp <[email protected]>
Signed-off-by: Philipp Jungkamp <[email protected]>
Signed-off-by: Philipp Jungkamp <[email protected]>
Signed-off-by: Philipp Jungkamp <[email protected]>
Signed-off-by: Philipp Jungkamp <[email protected]>
I'd like to also enable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The LinearAllocator
triggered the clang-analyzer
"dead-write" warning. I think this is definitely broken!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, im fine with leaving it as is for now.. I am not aware of anybody using this code.
Maybe @n-eiling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the FPGA code is only using the HostRamAllocator. What is a dead-write warning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A dead write is a write to non-volatile memory that is never read for the remainder of that memory's lifetime. This constructor modifies the function parameters after the member variables have been assigned by the member-initialization-list. This means that these modifications will just be discarded at the end of a function.
@stv0g I added the See https://github.com/nix-community/nix-ld?tab=readme-ov-file#usage |
Great work :-) This PR is getting a bit too large for confidently merging and reviewing it. Especially the clang-tidy commit (cab6e02) is quite big.. I would favour to merge this as is now, or splitting up the PR into smaller ones which can be merged immediatly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general this looks like it improves code quality quite a bit, espc. regarding override/virtual. However, I'm not convinced of adding const everywhere. Surely the compiler will do this optimization automatically. I doubt it adds much value during programming. I get the value for function parameters, especially if part of an interface, but for local variables I don't see the point.
I want us to focus on making contributions to VILLAS easier, and forcing people to use const everywhere may not be a move in this direction, or what do you think?
Also again: Please do not do style and logic changes in one PR, especially a PR of this size.
-Wall | ||
-Wno-unknown-pragmas | ||
-Wno-vla-cxx-extension | ||
-Wno-unused-command-line-argument |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you motivate why you introduced these new options?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GCC and Clang have a different set of warnings enabled with -Wall
. This silences two warnings that would, together with -Werror
break a Clang Build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't fixing them be more desireable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I introduced two new flags here.
-Wno-vla-cxx-extension
: Clang would issue a warning for each variable length array on the stack. This affects most node types.-Wno-unused-command-line-argument
: CMake seems to introduce-Wl,--compress-debug-sections
command line arguments which Clang doesn't understand and then warns on.
|
||
// libpci handle of the device | ||
const kernel::devices::PciDevice *pci_device; | ||
[[maybe_unused]] const kernel::devices::PciDevice *pci_device; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really something we want to introduce? It adds clutter to the code. In this instance, we should check whether we actually need this (now or in the future) and rather remove it.
Anything touching the FPGA code should be tested by someone with access to the FPGA before we should approve changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This private member variable was set in the constructor, yet never read or used anywhere. I didn't know whether this was some kind of guard variable keeping a PCI connection alive or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect it's a leftover from when vfio devices were always PCI devices. If it's really unused now, we can remove it.
auto line = std::unique_ptr<char, decltype(line_destructor)>{ | ||
line_ptr, line_destructor}; | ||
if (ret == -1) | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the point of this. It's way less readable than the C code. If you absolutely must use C++, then why not use proper C++ file I/O? Also any change here needs to be tested by someone with access to an FPGA.
FILE *f = fopen(PROCFS_PATH "/cmdline", "r"); | ||
auto file_destructor = [](FILE *file) { fclose(file); }; | ||
auto f = std::unique_ptr<FILE, decltype(file_destructor)>{ | ||
fopen(PROCFS_PATH "/cmdline", "r"), file_destructor}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here. I don't see the point of this change. Also needs FPGA testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-analyzer
found a control flow path that lead to fclose
not being called here. More specifically, it's missing an fclose
before the return 0; // FOUND
line. It also guards against leaks if an exception is thrown (I don't currently see any exception throwing code here, but I'd argue that using smart pointers for resource owning pointers is a better and less error-prone programming style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok makes sense. Still you are mixing C and C++ code here, which I think is a bit ugly. Also the syntax is quite a bit more complex. I'm fine with your change, but I would prefer switching to a C++ API, or fixing the existing code.
f = fopen(fn, "w+"); | ||
auto file_destructor = [](FILE *file) { fclose(file); }; | ||
auto f = std::unique_ptr<FILE, decltype(file_destructor)>{fopen(fn, "w+"), | ||
file_destructor}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same.
FILE *f = fopen(argv[1], "r"); | ||
auto file_destructor = [](FILE *file) { fclose(file); }; | ||
auto f = std::unique_ptr<FILE, decltype(file_destructor)>{ | ||
fopen(argv[1], "r"), file_destructor}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is less readable than the C code, and the better way would be to use C++ file I/O
"Sample data mismatch at index %d: %lld != %lld", j, | ||
a->data[j].i, b->data[j].i); | ||
"Sample data mismatch at index %d: %" PRId64 | ||
" != %" PRId64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this? Maybe better use C++ format functions if the C ones aren't sufficient?
#endif | ||
|
||
rewind(stream); | ||
(void)errno; // TODO: should we handle rewind errors? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe make an issue
p->many ? producer_consumer_many : producer_consumer, p); | ||
|
||
sleep(0.2); | ||
// sleep(0.2); TODO: Is this supposed to to something? Yield? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dead code. Can we understand why this was here before just removing it?
-not \( -path "${TOP_DIR}/fpga/thirdparty/*" -o -path "${TOP_DIR}/build*/*" \) | \ | ||
xargs clang-format --verbose -i | ||
git ls-files -c -z -- "*.c" ".h" "*.hpp" "*.cpp" ":!:fpga/thirdparty" |\ | ||
xargs -0 clang-format --verbose -i |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what are the implications of this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does everything as before, except it only formats files known to git and works with paths that contain spaces and even newlines.
And any changes on what we expect from contributions should also be added here: https://villas.fein-aachen.org/docs/node/development/contributing Let's not let this get out of date again. |
I want to emphasize that this PR is not yet ready. I just wanted to track the progress through the GitHub PR checklist and discuss what lints to enable initially. I want to split the large enable clang tidy commit by the lint that it fixed. I can also split out a base commit that just fixes the clang build. I'll also add a related PR to the style guide documentation before this is ready to review. |
Could we split out-some commits into small PRs please? There are multiple commits which deserve their own PR and we can review and merge those quicker. Thanks :) |
What is
clang-tidy
clang-tidy
is a linter developed as part of theclang-tools
. This linter makes use of the clang C/C++ compiler front end to analyze and lint based on the actual C/C++ AST instead of the typical regex-based lints used by e.g.cppcheck
.This allows
clang-tidy
to automatically fix some of the errors it detects automatically. It is also nicely integrated with other clang tooling like theclangd
language server.Progress
villas-node
usingclang
and fix compiler warnings/errorsmodernize-use-override
: Enfore CppCoreGuideline C.128. Refactor and cleanups #907 (comment)misc-const-correctness
: Addconst
to all variables that can be.clang-analyzer-*
: Use clang static analyzer to find memory leaks, null dereferences, use-after-free and other bugs hidden in control flow or non-exception-safe code.clang-tidy
automatically through cmake'sCMAKE_CXX_CLANG_TIDY
integration.