Skip to content

Commit 94c3c45

Browse files
committed
CheckUninitVar: Use function information from library, bailout for '?'
1 parent 26fa994 commit 94c3c45

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

lib/checkuninitvar.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,11 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
14371437
return true;
14381438
}
14391439

1440+
// bailout on ternary operator. TODO: This can be solved much better. For example, if the variable is not accessed in the branches of the ternary operator, we could just continue.
1441+
if (Token::Match(tok, "?")) {
1442+
return true;
1443+
}
1444+
14401445
if (Token::Match(tok, "return|break|continue|throw|goto")) {
14411446
if (noreturn)
14421447
*noreturn = true;
@@ -1729,16 +1734,16 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool all
17291734
if (arg) {
17301735
const bool address(vartok->previous()->str() == "&");
17311736
const Token *argStart = arg->typeStartToken();
1732-
while (argStart->previous() && argStart->previous()->isName())
1733-
argStart = argStart->previous();
1734-
if (!address && Token::Match(argStart, "const| struct| %type% [,)]"))
1735-
return true;
1736-
if (!address && Token::Match(argStart, "const| struct| %type% %var% [,)]"))
1737+
if (!address && Token::Match(argStart, "struct| %type% [,)]"))
17371738
return true;
1738-
if (Token::Match(argStart, "const %type% & %var% [,)]"))
1739+
if (!address && Token::Match(argStart, "struct| %type% %var% [,)]"))
17391740
return true;
17401741
if (pointer && !address && !alloc && Token::Match(argStart, "struct| %type% * %var% [,)]"))
17411742
return true;
1743+
while (argStart->previous() && argStart->previous()->isName())
1744+
argStart = argStart->previous();
1745+
if (Token::Match(argStart, "const %type% & %var% [,)]"))
1746+
return true;
17421747
if ((pointer || address) && !alloc && Token::Match(argStart, "const struct| %type% * %var% [,)]"))
17431748
return true;
17441749
if ((pointer || address) && Token::Match(argStart, "const %type% %var% [") && Token::Match(argStart->linkAt(3), "] [,)]"))
@@ -1748,6 +1753,12 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool all
17481753
} else if (Token::Match(start->previous(), "if|while|for")) {
17491754
// control-flow statement reading the variable "by value"
17501755
return !alloc;
1756+
} else {
1757+
bool isnullbad = _settings->library.isnullargbad(start->previous(), argumentNumber + 1);
1758+
bool isuninitbad = _settings->library.isuninitargbad(start->previous(), argumentNumber + 1);
1759+
if (alloc)
1760+
return isnullbad && isuninitbad;
1761+
return isuninitbad;
17511762
}
17521763
}
17531764
}

test/testuninitvar.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3832,7 +3832,7 @@ class TestUninitVar : public TestFixture {
38323832
" FILE *f;\n"
38333833
" fgets (s, n, f);\n"
38343834
"}");
3835-
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: f\n","", errout.str());
3835+
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: f\n",errout.str());
38363836

38373837
checkUninitVarB("void f(char * s, int n, FILE *f) {\n"
38383838
" fgets (s, n, f);\n"
@@ -3993,7 +3993,7 @@ class TestUninitVar : public TestFixture {
39933993
" int nbytes;\n"
39943994
" write(STDOUT_FILENO, buf, nbytes);\n"
39953995
"}");
3996-
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: nbytes\n", "", errout.str());
3996+
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: nbytes\n", errout.str());
39973997

39983998
checkUninitVarB("void no_uninitvar(char *buf, int nbytes)\n"
39993999
"{\n"

0 commit comments

Comments
 (0)