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());
//TRAC #7428 false negative: Statement is always false
check("void f() {\n"
"assert( (a & 0x07) == 8U );\n" // statement always false, because 7 == 8 is false
"assert( (a & 0x07) > 7U );\n" // statement always false, because 7 > 7 is false
"assert( (a | 0x07) < 7U );\n" // statement always false, because 7 < 7 is false
"assert( (a & 0x07) > 8U );\n" // statement always false, because 7 > 8 is false
"assert( (a | 0x07) < 6U );\n" // statement always false, because 7 < 6 is false
"assert( (a & 0x07) >= 7U );\n" // statement correct
"assert( (a | 0x07) <= 7U );\n" // statement correct
"assert( (a & 0x07) >= 8U );\n" // statement always false, because 7 >= 8 is false
"assert( (a | 0x07) <= 6U );\n" // statement always false, because 7 <= 6 is false
"assert( (a & 0x07) > 3U );\n" // statement correct
"assert( (a | 0x07) < 9U );\n" // statement correct
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X & 0x7) == 0x8' is always false.\n"
"[test.cpp:3]: (style) Expression '(X & 0x7) > 0x7' is always false.\n"
"[test.cpp:4]: (style) Expression '(X | 0x7) < 0x7' is always false.\n"
"[test.cpp:5]: (style) Expression '(X & 0x7) > 0x8' is always false.\n"
"[test.cpp:6]: (style) Expression '(X | 0x7) < 0x6' is always false.\n"
"[test.cpp:9]: (style) Expression '(X & 0x7) >= 0x8' is always false.\n"
"[test.cpp:10]: (style) Expression '(X | 0x7) <= 0x6' is always false.\n",
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)