ASSERT_EQUALS("[test.cpp:1]: (error) Signed integer overflow for expression '(long)0x10000*(long)0x10000'.\n", errout_str());
check("void foo() {\n"
" int intmax = 0x7fffffff;\n"
" return intmax + 1;\n"
"}",settings);
ASSERT_EQUALS("[test.cpp:3]: (error) Signed integer overflow for expression 'intmax+1'.\n", errout_str());
check("void foo() {\n"
" int intmax = 0x7fffffff;\n"
" return intmax - 1;\n"
"}",settings);
ASSERT_EQUALS("", errout_str());
check("int foo(signed int x) {\n"
" if (x==123456) {}\n"
" return x * x;\n"
"}",settings);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'x==123456' is redundant or there is signed integer overflow for expression 'x*x'.\n", errout_str());
check("int foo(signed int x) {\n"
" if (x==123456) {}\n"
" return -123456 * x;\n"
"}",settings);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'x==123456' is redundant or there is signed integer overflow for expression '-123456*x'.\n", errout_str());
check("int foo(signed int x) {\n"
" if (x==123456) {}\n"
" return 123456U * x;\n"
"}",settings);
ASSERT_EQUALS("", errout_str());
check("int f(int i) {\n"// #12117
" return (i == 31) ? 1 << i : 0;\n"
"}", settings);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (warning) Shifting signed 32-bit value by 31 bits is undefined behaviour. See condition at line 2.\n", errout_str());
ASSERT_EQUALS("[test.cpp:1]: (warning) Expression '-4' has a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout_str());
check("x = (unsigned)y * -4;", settingsDefault);
ASSERT_EQUALS("[test.cpp:1]: (warning) Expression '-4' has a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout_str());
check("unsigned int dostuff(int x) {\n"// x is signed
" if (x==0) {}\n"
" return (x-1)*sizeof(int);\n"
"}", settings);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Expression 'x-1' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout_str());
check("unsigned int f1(signed int x, unsigned int y) {"// x is signed
" return x * y;\n"
"}\n"
"void f2() { f1(-4,4); }", settingsDefault);
ASSERT_EQUALS(
"[test.cpp:1]: (warning) Expression 'x' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n",
errout_str());
check("unsigned int f1(int x) {"
" return x * 5U;\n"
"}\n"
"void f2() { f1(-4); }", settingsDefault);
ASSERT_EQUALS(
"[test.cpp:1]: (warning) Expression 'x' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n",
errout_str());
check("unsigned int f1(int x) {"// #6168: FP for inner calculation
" return 5U * (1234 - x);\n"// <- signed subtraction, x is not sign converted
"}\n"
"void f2() { f1(-4); }", settingsDefault);
ASSERT_EQUALS("", errout_str());
// Don't warn for + and -
check("void f1(int x) {"
" a = x + 5U;\n"
"}\n"
"void f2() { f1(-4); }", settingsDefault);
ASSERT_EQUALS("", errout_str());
check("size_t foo(size_t x) {\n"
" return -2 * x;\n"
"}", settingsDefault);
ASSERT_EQUALS("[test.cpp:2]: (warning) Expression '-2' has a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout_str());
ASSERT_EQUALS("[test.cpp:2]: (style) int result is assigned to long variable. If the variable is long to avoid loss of information, then you have loss of information.\n", errout_str());
check(code, settingsWin);
ASSERT_EQUALS("", errout_str());
check("long f(int x, int y) {\n"
" long ret = x * y;\n"
" return ret;\n"
"}\n", settings);
ASSERT_EQUALS("[test.cpp:2]: (style) int result is assigned to long variable. If the variable is long to avoid loss of information, then you have loss of information.\n", errout_str());
check("long f() {\n"
" const long long ret = 256 * (1 << 10);\n"
" return ret;\n"
"}\n", settings);
ASSERT_EQUALS("", errout_str());
// typedef
check("long f(int x, int y) {\n"
" const size_t ret = x * y;\n"
" return ret;\n"
"}\n", settings);
ASSERT_EQUALS("", errout_str());
// astIsIntResult
check("long f(int x, int y) {\n"
" const long ret = (long)x * y;\n"
" return ret;\n"
"}\n", settings);
ASSERT_EQUALS("", errout_str());
check("double g(float f) {\n"
" return f * f;\n"
"}\n", settings);
ASSERT_EQUALS("[test.cpp:2]: (style) float result is returned as double value. If the return value is double to avoid loss of information, then you have loss of information.\n",
ASSERT_EQUALS("[test.cpp:2]: (style) int result is returned as long value. If the return value is long to avoid loss of information, then you have loss of information.\n", errout_str());
check(code, settingsWin);
ASSERT_EQUALS("", errout_str());
constchar code2[] = "long long f(int x, int y) {\n"
" return x * y;\n"
"}\n";
check(code2, settings);
ASSERT_EQUALS("[test.cpp:2]: (style) int result is returned as long long value. If the return value is long long to avoid loss of information, then you have loss of information.\n", errout_str());
check(code2, settingsWin);
ASSERT_EQUALS("[test.cpp:2]: (style) int result is returned as long long value. If the return value is long long to avoid loss of information, then you have loss of information.\n", errout_str());
// typedef
check("size_t f(int x, int y) {\n"
" return x * y;\n"
"}\n", settings);
ASSERT_EQUALS("[test.cpp:2]: (style) int result is returned as long value. If the return value is long to avoid loss of information, then you have loss of information.\n", errout_str());
}
// This function ensure that test works with different compilers. Floats can