-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Could we help static analyzers know a single SECTION is executed? #2681
Comments
clang-tidy has the same issue. I am not aware of any reasonable way of solving this for clang-tidy either. |
Well, clang-tidy is analyzing functions and translation units individually, but Coverity is doing a global analysis, so it would be possible to add an assert at a higher level that a single section is active per iteration. |
It's kind of a hack but for clang-tidy we can check if #include <string>
#include <catch2/catch_test_macros.hpp>
#ifdef __clang_analyzer__
#undef TEST_CASE
#define TEST_CASE(...) void INTERNAL_CATCH_UNIQUE_NAME(TestCase)([[maybe_unused]] int sectionHint)
#undef SECTION
#define SECTION(...) if (sectionHint == __LINE__)
#endif
TEST_CASE("Example")
{
std::string foo;
SECTION("A")
{
std::string a = std::move(foo);
}
SECTION("B")
{
std::string b = std::move(foo);
}
} |
Tested in compiler explorer https://godbolt.org/z/3eTxTvch7 I also made a few changes to make it work with nested sections. |
Wow, great idea, didn't think of using |
Yeah the godbolt link shows how to make it work with nested sections. The trick is to shadow the int GetNewSectionHint();
#define SECTION(...) if ([[maybe_unused]] int tmpHint = sectionHint, sectionHint = GetNewSectionHint(); tmpHint == __LINE__) |
This is fixing the issue for me, by I guess now the question is if this is built-in for Coverity, clang-tidy, etc. so that people don't search for a solution again. |
@vberlier I like the idea, and the change should not be too annoying to maintain. One question though: does |
@horenmar clang-tidy will understand anything the Clang it is based on understands, so the question is more if people are using C++14-based clang-tidy. I tend to think for tools like clang-tidy and Coverity you use something recent to get the best value out of it, but I cannot speak for others. If you prefer, you can just provide a define we use for static analyzers. If you want to support some static analyzers built-in, you can use __COVERITY__ for Coverity BTW. |
For Personally I think it would be fine to implement this as a progressive enhancement. Catch would simply work a bit better with static analyzers when C++17 or higher is detected. #if __cplusplus >= 201703L && (defined(__clang_analyzer__) || defined(__COVERITY__)) |
Okay, so I implemented this and ran into an issue: I used this as my test case TEST_CASE( "Example" ) {
std::string foo = "hello";
SECTION( "A" ) {
std::string a = std::move(foo);
CHECK( a == "hello" );
}
SECTION( "Group" ) {
SECTION( "B" ) {
std::string b = std::move( foo );
CHECK( b == "hello" );
}
SECTION( "C" ) {
std::string c = std::move( foo );
CHECK(c == "hello");
//// should only emit warning here
//std::string d = std::move( foo );
//CHECK( d == "hello" );
}
}
} When I run clang-tidy-17 through CMake, with this
I still get warnings about use-after-move
It's all in the branch |
The I tested it and with |
Whyyyy are there differently named checks for using moved-from objects with different quality of checking? |
Honestly I'm not completely sure, it's kind of confusing. Most projects run By the way I'm thinking that the |
We're running Coverity to analyze our code base, and if we do std::move of the same thing in multiple SECTION, Coverity will complain that if, for example, both
catch_internal_Section258->operator bool()
andcatch_internal_Section259->operator bool()
are true, then we end touching which was moved. I understand it's much simpler to generate aif
for each SECTION, but if it would be great if we could find a way to tell the static analyzer that a single section is active at the same time. For example, maybe all the booleans are in a bitfield and we assert that a single bit is set. Generating else if/switch-case would work, but I cannot think of a way to make it work with just SECTION. We discussed the idea of adding DECLARE_SECTIONS(name1, name2, ...) to add an assert to help the static analyzer. I'm creating this issue without any clear solution in mind, but more to brainstorm if we have any idea for a solution.The text was updated successfully, but these errors were encountered: