Fix disabled valueFlowUninit tests (#3262)

This commit is contained in:
Paul Fultz II 2021-05-21 00:28:34 -05:00 committed by GitHub
parent 4746d4b819
commit 5409fa8afd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 15 deletions

View File

@ -1820,7 +1820,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
while (Token::simpleMatch(tok2->astParent(), "*") || while (Token::simpleMatch(tok2->astParent(), "*") ||
(Token::simpleMatch(tok2->astParent(), ".") && !Token::simpleMatch(tok2->astParent()->astParent(), "(")) || (Token::simpleMatch(tok2->astParent(), ".") && !Token::simpleMatch(tok2->astParent()->astParent(), "(")) ||
(Token::simpleMatch(tok2->astParent(), "[") && tok2 == tok2->astParent()->astOperand1())) { (Token::simpleMatch(tok2->astParent(), "[") && tok2 == tok2->astParent()->astOperand1())) {
if (Token::simpleMatch(tok2->astParent(), "*") || tok2->astParent()->originalName() == "->") if (tok2->astParent()->isUnaryOp("*") || (astIsLHS(tok2) && tok2->astParent()->originalName() == "->"))
derefs++; derefs++;
if (derefs > indirect) if (derefs > indirect)
break; break;

View File

@ -1449,6 +1449,15 @@ void CheckUninitVar::valueFlowUninit()
} }
if (!tok->variable() && !tok->isUnaryOp("*")) if (!tok->variable() && !tok->isUnaryOp("*"))
continue; continue;
if (Token::Match(tok, "%name% ("))
continue;
const Token* parent = tok->astParent();
while (Token::simpleMatch(parent, "."))
parent = parent->astParent();
if (parent && parent->isUnaryOp("&"))
continue;
if (isVoidCast(parent))
continue;
auto v = std::find_if(tok->values().begin(), tok->values().end(), std::mem_fn(&ValueFlow::Value::isUninitValue)); auto v = std::find_if(tok->values().begin(), tok->values().end(), std::mem_fn(&ValueFlow::Value::isUninitValue));
if (v == tok->values().end()) if (v == tok->values().end())
continue; continue;
@ -1458,10 +1467,10 @@ void CheckUninitVar::valueFlowUninit()
continue; continue;
bool uninitderef = false; bool uninitderef = false;
if (tok->variable()) { if (tok->variable()) {
if (!isVariableUsage(tok, tok->variable()->isPointer(), tok->variable()->isArray() ? ARRAY : NO_ALLOC, v->indirect))
continue;
bool unknown; bool unknown;
const bool deref = CheckNullPointer::isPointerDeRef(tok, unknown, mSettings); const bool isarray = !tok->variable() || tok->variable()->isArray();
const bool ispointer = astIsPointer(tok) && !isarray;
const bool deref = ispointer && CheckNullPointer::isPointerDeRef(tok, unknown, mSettings);
if (v->indirect == 1 && !deref) if (v->indirect == 1 && !deref)
continue; continue;
uninitderef = deref && v->indirect == 0; uninitderef = deref && v->indirect == 0;
@ -1469,13 +1478,11 @@ void CheckUninitVar::valueFlowUninit()
if (Token::Match(tok->astParent(), ". %var%") && !isleaf) if (Token::Match(tok->astParent(), ". %var%") && !isleaf)
continue; continue;
} }
if (!Token::Match(tok->astParent(), ". %name% (") && !uninitderef && isVariableChanged(tok, v->indirect, mSettings, mTokenizer->isCPP())) if (!(Token::Match(tok->astParent(), ". %name% (") && uninitderef) &&
isVariableChanged(tok, v->indirect, mSettings, mTokenizer->isCPP()))
continue; continue;
uninitvarError(tok, tok->expressionString(), v->errorPath); uninitvarError(tok, tok->expressionString(), v->errorPath);
const Token * nextTok = tok; const Token* nextTok = nextAfterAstRightmostLeaf(parent);
while (Token::simpleMatch(nextTok->astParent(), "."))
nextTok = nextTok->astParent();
nextTok = nextAfterAstRightmostLeaf(nextTok);
if (nextTok == scope.bodyEnd) if (nextTok == scope.bodyEnd)
break; break;
tok = nextTok ? nextTok : tok; tok = nextTok ? nextTok : tok;

View File

@ -4346,6 +4346,7 @@ private:
"{\n" "{\n"
" int *x;\n" " int *x;\n"
" int *&y = x;\n" " int *&y = x;\n"
" y = nullptr;\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
@ -4469,7 +4470,9 @@ private:
" arc << p;\n" " arc << p;\n"
" return *p;\n" " return *p;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: p\n"
"[test.cpp:4]: (error) Uninitialized variable: p\n",
errout.str());
// #4320 // #4320
valueFlowUninit("void f() {\n" valueFlowUninit("void f() {\n"
@ -4477,7 +4480,9 @@ private:
" a << 1;\n" " a << 1;\n"
" return a;\n" " return a;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n"
"[test.cpp:4]: (error) Uninitialized variable: a\n",
errout.str());
// #9750 // #9750
valueFlowUninit("struct S {\n" valueFlowUninit("struct S {\n"
@ -4766,7 +4771,7 @@ private:
" int * x = &s1.x;\n" " int * x = &s1.x;\n"
" struct S s2 = {*x, 0};\n" " struct S s2 = {*x, 0};\n"
"}"); "}");
// TODO ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:9]: (error) Uninitialized variable: *x\n", errout.str()); ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:9]: (error) Uninitialized variable: *x\n", errout.str());
valueFlowUninit("struct S {\n" valueFlowUninit("struct S {\n"
" int x;\n" " int x;\n"
@ -4779,7 +4784,7 @@ private:
" int * x = &s1.x;\n" " int * x = &s1.x;\n"
" s2.x = *x;\n" " s2.x = *x;\n"
"}"); "}");
// TODO ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:10]: (error) Uninitialized variable: *x\n", errout.str()); ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:10]: (error) Uninitialized variable: *x\n", errout.str());
valueFlowUninit("void f(bool * x) {\n" valueFlowUninit("void f(bool * x) {\n"
" *x = false;\n" " *x = false;\n"
@ -4816,7 +4821,7 @@ private:
" A b;\n" " A b;\n"
" f(&b);\n" " f(&b);\n"
"}"); "}");
// TODO ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
valueFlowUninit("std::string f() {\n" valueFlowUninit("std::string f() {\n"
" std::ostringstream ostr;\n" " std::ostringstream ostr;\n"
@ -4874,7 +4879,7 @@ private:
" A c;\n" " A c;\n"
" return d(&c);\n" " return d(&c);\n"
"}"); "}");
// TODO ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// # 9302 // # 9302
valueFlowUninit("struct VZ {\n" valueFlowUninit("struct VZ {\n"
@ -4926,6 +4931,7 @@ private:
" g(&copied_all, 5, 6, &bytesCopied);\n" " g(&copied_all, 5, 6, &bytesCopied);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:2]: (error) Uninitialized variable: *buflen\n", errout.str()); ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:2]: (error) Uninitialized variable: *buflen\n", errout.str());
} }
void uninitvar_memberfunction() { void uninitvar_memberfunction() {
@ -4938,6 +4944,16 @@ private:
" if (c->x() == 4) {}\n" " if (c->x() == 4) {}\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: c\n", errout.str()); ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: c\n", errout.str());
valueFlowUninit("struct A { \n"
" int i; \n"
" void f();\n"
"};\n"
"void g() {\n"
" A a;\n"
" a.f();\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void uninitvar_nonmember() { void uninitvar_nonmember() {