const & r ) {\n"
" px = r.px;\n"
" return *this;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void clarifyCondition7() {
// Ensure that binary and unary &, and & in declarations are distinguished properly
check("void f(bool error) {\n"
" bool & withoutSideEffects=found.first->second;\n" // Declaring a reference to a boolean; & is no operator at all
" execute(secondExpression, &programMemory, &result, &error);\n" // Unary &
"}");
ASSERT_EQUALS("", errout.str());
}
void testBug5895() {
check("void png_parse(uint64_t init, int buf_size) {\n"
" if (init == 0x89504e470d0a1a0a || init == 0x8a4d4e470d0a1a0a)\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void testBug5309() {
check("extern uint64_t value;\n"
"void foo() {\n"
" if( ( value >= 0x7ff0000000000001ULL )\n"
" && ( value <= 0x7fffffffffffffffULL ) );\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void alwaysTrue() {
check("void f() {\n" // #4842
" int x = 0;\n"
" if (a) { return; }\n" // <- this is just here to fool simplifyKnownVariabels
" if (!x) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Condition '!x' is always true\n", errout.str());
check("void f() {\n" // #6898 (Token::expressionString)
" int x = 0;\n"
" A(x++ == 1);\n"
" A(x++ == 2);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'x++==1' is always false\n"
"[test.cpp:4]: (style) Condition 'x++==2' is always false\n",
errout.str());
// Avoid FP when condition comes from macro
check("void f() {\n"
" int x = 0;\n"
" if (a) { return; }\n" // <- this is just here to fool simplifyKnownVariabels
" if ($!x) {}\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" int x = 0;\n"
" if (a) { return; }\n" // <- this is just here to fool simplifyKnownVariabels
" if ($x != $0) {}\n"
"}");
ASSERT_EQUALS("", errout.str());
// Don't warn in assertions. Condition is often 'always true' by intention.
// If platform,defines,etc cause an 'always false' assertion then that is not very dangerous neither
check("void f() {\n"
" int x = 0;\n"
" assert(x == 0);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void checkInvalidTestForOverflow() {
check("void f(char *p, unsigned int x) {\n"
" assert((p + x) < p);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow '(p+x)= p);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow '(p+x)>=p'. Condition is always true unless there is overflow, and overflow is UB.\n", errout.str());
check("void f(char *p, unsigned int x) {\n"
" assert(p > (p + x));\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow 'p>(p+x)'. Condition is always false unless there is overflow, and overflow is UB.\n", errout.str());
check("void f(char *p, unsigned int x) {\n"
" assert(p <= (p + x));\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow 'p<=(p+x)'. Condition is always true unless there is overflow, and overflow is UB.\n", errout.str());
check("void f(signed int x) {\n"
" assert(x + 100 < x);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow 'x+100 dont warn
" assert(x + 100U < x);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
};
REGISTER_TEST(TestCondition)