Fixed #4896 (FP Uninitialized variable on template function)

This commit is contained in:
Daniel Marjamäki 2013-10-26 18:39:40 +02:00
parent 8687e85e56
commit 51ad9ab6ac
2 changed files with 45 additions and 11 deletions

View File

@ -373,6 +373,8 @@ private:
break; break;
if (Token::Match(tok2, "%var% (")) if (Token::Match(tok2, "%var% ("))
break; break;
if (Token::Match(tok2, "%var% <") && Token::Match(tok2->linkAt(1), "> ("))
break;
if (tok2->varId() && if (tok2->varId() &&
!Token::Match(tok2->previous(), "&|::") && !Token::Match(tok2->previous(), "&|::") &&
!Token::simpleMatch(tok2->tokAt(-2), "& (") && !Token::simpleMatch(tok2->tokAt(-2), "& (") &&
@ -477,17 +479,7 @@ private:
if (tok.varId()) { if (tok.varId()) {
// array variable passed as function parameter.. // array variable passed as function parameter..
if (Token::Match(tok.previous(), "[(,] %var% [+-,)]")) { if (Token::Match(tok.previous(), "[(,] %var% [+-,)]")) {
// skip ')'..
const Token *tok2 = tok.next();
while (tok2 && tok2->str() == ")")
tok2 = tok2->next();
// variable is assigned like: "( %var% ) .. ="
if (Token::Match(tok.previous(), "( %var% )") && tok2 && tok2->str() == "=")
ExecutionPath::bailOutVar(checks, tok.varId()); ExecutionPath::bailOutVar(checks, tok.varId());
else if (tok.strAt(-2) != ">" || !tok.linkAt(-2))
use(checks, &tok);
//use_array(checks, &tok);
return &tok; return &tok;
} }

View File

@ -1740,6 +1740,13 @@ private:
" int i;\n" " int i;\n"
" x(i+2);\n" " x(i+2);\n"
"}"); "}");
ASSERT_EQUALS("", errout.str());
checkUninitVar2("void f()\n"
"{\n"
" int i;\n"
" x(i+2);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
checkUninitVar("void f()\n" checkUninitVar("void f()\n"
@ -1777,6 +1784,14 @@ private:
" int x;\n" " int x;\n"
" foo(x);\n" " foo(x);\n"
"}"); "}");
ASSERT_EQUALS("", errout.str());
checkUninitVar2("int foo(int x) { return x; }\n"
"void f2()\n"
"{\n"
" int x;\n"
" foo(x);\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: x\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: x\n", errout.str());
checkUninitVar("void foo(const char *s)\n" checkUninitVar("void foo(const char *s)\n"
@ -1823,6 +1838,20 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVar("void test() {\n"
" double d;\n"
" double x = dostuff<int>(d);\n"
" return x;\n"
"}");
ASSERT_EQUALS("", errout.str());
checkUninitVar("template <class T> double dostuff(int x, T &y);\n"
"void test() {\n"
" double d;\n"
" a = dostuff<double>(0, d);\n"
"}");
ASSERT_EQUALS("", errout.str());
// using uninitialized function pointer.. // using uninitialized function pointer..
checkUninitVar("void foo()\n" checkUninitVar("void foo()\n"
"{\n" "{\n"
@ -1913,6 +1942,13 @@ private:
" int x;\n" " int x;\n"
" a(x);\n" " a(x);\n"
"}").c_str()); "}").c_str());
ASSERT_EQUALS("", errout.str());
checkUninitVar2((funca +
"void b() {\n"
" int x;\n"
" a(x);\n"
"}").c_str());
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
checkUninitVar((funca + checkUninitVar((funca +
@ -1942,6 +1978,12 @@ private:
" int *p;\n" " int *p;\n"
" a(p);\n" " a(p);\n"
"}").c_str()); "}").c_str());
ASSERT_EQUALS("", errout.str());
checkUninitVar2((funca +
"void b() {\n"
" int *p;\n"
" a(p);\n"
"}").c_str());
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: p\n", errout.str());
} }