Add more tests for valueFlowUninit (#2124)

This commit is contained in:
Paul Fultz II 2019-08-30 01:41:17 -05:00 committed by amai2012
parent a501f65c8c
commit 2942be53f7
2 changed files with 279 additions and 1 deletions

View File

@ -2510,7 +2510,7 @@ static bool valueFlowForward(Token * const startToken,
return false;
}
else if (indentlevel <= 0 && Token::Match(tok2, "return|throw"))
else if (indentlevel <= 0 && Token::Match(tok2, "return|throw|setjmp|longjmp"))
returnStatement = true;
else if (returnStatement && tok2->str() == ";")

View File

@ -3991,6 +3991,284 @@ private:
" int x[] = {a,2};\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
valueFlowUninit("void foo()\n"
"{\n"
" int x;\n"
" int *y = &x;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void foo()\n"
"{\n"
" int *x;\n"
" int *&y = x;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void foo()\n"
"{\n"
" int x = xyz::x;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void f()\n"
"{\n"
" extern int a;\n"
" a++;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("static void foo()\n"
"{\n"
" int x, y;\n"
" x = (y = 10);\n"
" int z = y * 2;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("static void foo() {\n"
" int x, y;\n"
" x = ((y) = 10);\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("static void foo()\n"
"{\n"
" Foo p;\n"
" p.abcd();\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("static void foo()\n"
"{\n"
" Foo p;\n"
" int x = p.abcd();\n"
"}");
ASSERT_EQUALS("", errout.str());
// Unknown types
{
valueFlowUninit("void a()\n"
"{\n"
" A ret;\n"
" return ret;\n"
"}");
ASSERT_EQUALS("", errout.str());
// #3916 - avoid false positive
valueFlowUninit("void f(float x) {\n"
" union lf { long l; float f; } u_lf;\n"
" float hx = (u_lf.f = (x), u_lf.l);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
valueFlowUninit("void a()\n"
"{\n"
" int x[10];\n"
" int *y = x;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void a()\n"
"{\n"
" int x;\n"
" int *y = &x;\n"
" *y = 0;\n"
" x++;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void a()\n"
"{\n"
" char x[10], y[10];\n"
" char *z = x;\n"
" memset(z, 0, sizeof(x));\n"
" memcpy(y, x, sizeof(x));\n"
"}");
ASSERT_EQUALS("", errout.str());
// Handling >> and <<
{
valueFlowUninit("int a() {\n"
" int ret;\n"
" std::cin >> ret;\n"
" ret++;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void f(int b) {\n"
" int a;\n"
" std::cin >> b >> a;\n"
" return a;"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void foo() {\n" // #3707
" Node node;\n"
" int x;\n"
" node[\"abcd\"] >> x;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("int a(FArchive &arc) {\n"
" int *p;\n"
" arc << p;\n"
" return *p;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
// #4320
valueFlowUninit("void f() {\n"
" int a;\n"
" a << 1;\n"
" return a;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
}
valueFlowUninit("void a() {\n" // asm
" int x;\n"
" asm();\n"
" x++;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void a()\n"
"{\n"
" int x[10];\n"
" struct xyz xyz1 = { .x = x };\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void foo()\n"
"{\n"
" char *buf = malloc(100);\n"
" struct ABC *abc = buf;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("class Fred {\n"
"public:\n"
" FILE *f;\n"
" ~Fred();\n"
"}\n"
"Fred::~Fred()\n"
"{\n"
" fclose(f);\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void f()\n"
"{\n"
" int c;\n"
" ab(sizeof(xyz), &c);\n"
" if (c);\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void f()\n"
"{\n"
" int c;\n"
" a = (f2(&c));\n"
" c++;\n"
"}");
ASSERT_EQUALS("", errout.str());
// goto/setjmp/longjmp..
valueFlowUninit("void foo(int x)\n"
"{\n"
" long b;\n"
" if (g()) {\n"
" b =2;\n"
" goto found;\n"
" }\n"
"\n"
" return;\n"
"\n"
"found:\n"
" int a = b;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("int foo()\n"
"{\n"
" jmp_buf env;\n"
" int a;\n"
" int val = setjmp(env);\n"
" if(val)\n"
" return a;\n"
" a = 1;\n"
" longjmp(env, 1);\n"
"}");
ASSERT_EQUALS("", errout.str());
// macro_for..
valueFlowUninit("int foo()\n"
"{\n"
" int retval;\n"
" if (condition) {\n"
" for12(1,2) { }\n"
" retval = 1;\n"
" }\n"
" else\n"
" retval = 2;\n"
" return retval;\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("int foo()\n"
"{\n"
" int i;\n"
" goto exit;\n"
" i++;\n"
"exit:\n"
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("int foo() {\n"
" int x,y=0;\n"
"again:\n"
" if (y) return x;\n"
" x = a;\n"
" y = 1;\n"
" goto again;\n"
"}");
ASSERT_EQUALS("", errout.str());
// #4040 - False positive
valueFlowUninit("int f(int x) {\n"
" int iter;\n"
" {\n"
" union\n"
" {\n"
" int asInt;\n"
" double asDouble;\n"
" };\n"
"\n"
" iter = x;\n"
" }\n"
" return 1 + iter;\n"
"}");
ASSERT_EQUALS("", errout.str());
// C++11 style initialization
valueFlowUninit("int f() {\n"
" int i = 0;\n"
" int j{ i };\n"
" return j;\n"
"}");
ASSERT_EQUALS("", errout.str());
// Ticket #5646
valueFlowUninit("float foo() {\n"
" float source[2] = {3.1, 3.1};\n"
" float (*sink)[2] = &source;\n"
" return (*sink)[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void uninitvar_ipa() {