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

Evaluate argument of (DYNAMIC_)SECTION, TEST_CASE in static-analysis mode #2817

Merged

Conversation

mjerabek
Copy link
Contributor

@mjerabek mjerabek commented Feb 19, 2024

Description

As the title says, it's fairly straightforward.

And also add configuration for clang-tidy, run it in CI, and fix/suppress the resulting warnings.

GitHub Issues

Closes #2816

@mjerabek
Copy link
Contributor Author

Not sure if/where should I add tests for this.

@mjerabek mjerabek changed the title Evaluate argument of (DYNAMIC_)SECTION in static-analysis mode Evaluate argument of (DYNAMIC_)SECTION, TEST_CASE in static-analysis mode Feb 19, 2024
Copy link

codecov bot commented Feb 19, 2024

Codecov Report

Attention: Patch coverage is 96.87500% with 1 lines in your changes are missing coverage. Please review.

Project coverage is 91.16%. Comparing base (c3fd4eb) to head (fcc7c07).

Additional details and impacted files
@@            Coverage Diff             @@
##            devel    #2817      +/-   ##
==========================================
- Coverage   91.20%   91.16%   -0.04%     
==========================================
  Files         197      197              
  Lines        8374     8381       +7     
==========================================
+ Hits         7637     7640       +3     
- Misses        737      741       +4     

@horenmar
Copy link
Member

I am reasonably sure that this breaks SECTION macros in some cases, so a test would be nice 😛 .

This is a valid SECTION start: SECTION("short", "long description with many many words"), and unless I am very mistaken, your change would break it.

@mjerabek
Copy link
Contributor Author

Huh, interesting. I had no idea it can be used like that 😄

Any tips where the tests for this should be?

@mjerabek mjerabek force-pushed the fix-static-analysis-sections-warnings branch from e63e8de to e3c7866 Compare February 21, 2024 22:08
@mjerabek
Copy link
Contributor Author

  • fixed the implementation (yes, the tests uncovered other bugs)
  • added basic clang-tidy run to CI

Some limitations:

  • Some files are checked multiple times, because they are present in compile_commands.json multiple times with different compile options. Also I'm quite certain that run-clang-tidy doesn't handle this well and we run it multiple times with the same configuration.
  • run-clang-tidy doesn't stop on error, so it always runs in full. If we used cmake's clang-tidy integration, we could rely on ninja. But cmake doesn't support running clang-tidy without also running the compiler, so it would either take longer, or we would have to fake a "null compiler" (I've done that in work, it works well, but it's not very nice). Or we could put together a short python script that generates a ninja build file and run that (I would probably slightly prefer that to the current solution, as we could also better deal with duplicate files in compile_commands.json).
  • Only the default checks are enabled at the moment. We should probably explicitly define what we want to check and what we want to consider an error.
  • If there are errors, the job fails (good). But we ignore any warnings. 🤷

Also, I might add some clang-tidy-specific tests later to test that clang-tidy understands that REQUIRE(expr) implies expr (and also implement it, because now it most probably cannot understand that). But that's for a follow-up PR.

@mjerabek mjerabek marked this pull request as draft February 22, 2024 10:51
# Extras and examples with clang-tidy-10
- version: "10"
tidy_options: ''
build_description: Extras + Examples
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
build_description: Extras + Examples
build_description: clang-tidy

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.

"clang-tidy" is already included in the job description. I've replaced this by "all", but it's not really completely all. I guess it's hard to put variant-specific description when there is just one variant.

Copy link
Member

Choose a reason for hiding this comment

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

Right, then "extras + examples" is fine.

@horenmar
Copy link
Member

run-clang-tidy doesn't stop on error, so it always runs in full. If we used cmake's clang-tidy integration, we could rely on ninja. But cmake doesn't support running clang-tidy without also running the compiler, so it would either take longer, or we would have to fake a "null compiler" (I've done that in work, it works well, but it's not very nice). Or we could put together a short python script that generates a ninja build file and run that (I would probably slightly prefer that to the current solution, as we could also better deal with duplicate files in compile_commands.json).

That's not great. Maybe we could merge the clang-tidy check into an already existing build? This would create a build with outsized build time, but we can't build all the builds in parallel either way, so as long as it gets scheduled reasonably early it shouldn't have much impact.

Some files are checked multiple times, because they are present in compile_commands.json multiple times with different compile options. Also I'm quite certain that run-clang-tidy doesn't handle this well and we run it multiple times with the same configuration.

Yes, they are indeed compiled multiple times in the full test build. Some tests require building against custom configuration of the implementation binary, so they have to rebuild it. You can find them quickly by looking for targets that link against Catch2_buildall_interface.

Only the default checks are enabled at the moment. We should probably explicitly define what we want to check and what we want to consider an error.

Definitely. The checks in clang-tidy can be a mess, with overlapping checks with different implementation, this came up in the original discussion for the static-analysis mode. Having a reasonable set that we can point to as being supported would be nice.

Also, I might add some clang-tidy-specific tests later to test that clang-tidy understands that REQUIRE(expr) implies expr (and also implement it, because now it most probably cannot understand that).

It almost definitely cannot understand it. The reasoning there is only slightly simpler than figuring out SECTIONs, and the analyzer helper mode has to help with those a lot. However, from cursory check, there is a relatively reasonable way of telling clang-tidy about custom assertions. It would require making the REQUIRE macro also change its definition based on the defines though.

@mjerabek mjerabek force-pushed the fix-static-analysis-sections-warnings branch from da16234 to 6e8ab59 Compare February 25, 2024 22:50
@mjerabek
Copy link
Contributor Author

In the end, I have rewritten the CI job to use cmake to run clang-tidy, with a fake compiler (turned out it's not messy when you're not adding PCHs and ccache into the mix, which I now realize are both useless for just clang-tidy run; oh well, I'm putting that on the endless list of pending CI refactorings).

The clang-tidy checks are now explicitly configured. The rationale is following: allow-list whole categories, deny-list particular checks from the categories. This way, when a new clang version adds new checks, they are easily discovered (if they print a warning) and may be acted upon - either fix the findings or disable the check if it is deemed not useful. YMMV

Werror is enabled for some concrete checks.

Unfortunately, we cannot enable bugprone-use-after-move. First, it cannot be made to understand our custom unique_ptr (llvm/llvm-project#36901). Second, it doesn't understand that if (i == 1) and if (i == 2) are exclusive, so it doesn't work with the SECTION hinting.

We also have to disable bugprone-macro-repeated-side-effects because if wrongly triggers for CATCH_MOVE and CATCH_FORWARD, although the second expansion of the macro argument is in unevaluated context (no issue for that yet AFAICT).

@mjerabek mjerabek force-pushed the fix-static-analysis-sections-warnings branch from b984a7b to 09c1359 Compare February 25, 2024 23:28
@mjerabek mjerabek marked this pull request as ready for review February 25, 2024 23:28
@mjerabek mjerabek force-pushed the fix-static-analysis-sections-warnings branch 2 times, most recently from bd1bc51 to 2f514ae Compare March 1, 2024 11:28
@mjerabek
Copy link
Contributor Author

mjerabek commented Mar 1, 2024

So, I have split each check to its separate commit as you wanted. It's up to you now to select which ones do you want to keep and which ones you want to suppress instead.

@mjerabek mjerabek force-pushed the fix-static-analysis-sections-warnings branch from 2f514ae to b5ddc42 Compare March 1, 2024 11:36
@@ -117,7 +117,7 @@ namespace Catch {
auto kv = splitKVPair( parts[i] );
auto key = kv.key, value = kv.value;

if ( key.empty() || value.empty() ) {
if ( key.empty() || value.empty() ) { // NOLINT(bugprone-branch-clone)
Copy link
Member

Choose a reason for hiding this comment

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

What's supposed to be duplicated 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.

The else branch waaay down.

Copy link
Member

Choose a reason for hiding this comment

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

ugh, that's dumb

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Very 😄

@mjerabek mjerabek force-pushed the fix-static-analysis-sections-warnings branch from b5ddc42 to 4bcbf60 Compare March 1, 2024 15:31
@mjerabek mjerabek force-pushed the fix-static-analysis-sections-warnings branch 2 times, most recently from fcb1495 to ed35b1c Compare March 1, 2024 16:23
@horenmar horenmar force-pushed the fix-static-analysis-sections-warnings branch from ed35b1c to fcc7c07 Compare March 1, 2024 19:50
* bugprone-branch-clone
* bugprone-copy-constructor-init
* bugprone-empty-catch
* bugprone-sizeof-expression
* bugprone-switch-missing-default-case
* bugprone-unused-local-non-trivial-variable
* clang-analyzer-core.uninitialized.Assign
* clang-analyzer-cplusplus.Move
* clang-analyzer-optin.cplusplus.VirtualCall
* modernize-loop-convert
* modernize-raw-string-literal
* modernize-use-equals-default
* modernize-use-override
* modernize-use-using
* performance-avoid-endl
* performance-inefficient-string-concatenation
* performance-inefficient-vector-operation
* performance-noexcept-move-constructor
* performance-unnecessary-value-param (and improve generator example)
* readability-duplicate-include
* readability-inconsistent-declaration-parameter-name
* readability-non-const-parameter
* readability-redundant-casting
* readability-redundant-member-init
* readability-redundant-smartptr-get
* readability-static-accessed-through-instance
* unused variable in amalgamted tests
@horenmar horenmar force-pushed the fix-static-analysis-sections-warnings branch from fcc7c07 to c700cae Compare March 1, 2024 20:24
@horenmar horenmar merged commit b20b365 into catchorg:devel Mar 1, 2024
62 of 63 checks passed
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.

Wunused-variable in (DYNAMIC_)SECTION when CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT is enabled
2 participants