Fix crashes in followVarExpression (#1358)

* Fix crashes in followVarExpression

* Add a regression test for issue 8717

* Skip reference declarations
This commit is contained in:
Paul Fultz II 2018-09-02 01:28:53 -05:00 committed by Daniel Marjamäki
parent 215bc3b303
commit 8353f94b93
2 changed files with 40 additions and 1 deletions

View File

@ -163,7 +163,10 @@ static const Token * followVariableExpression(const Token * tok, bool cpp)
if (tok->astParent() && tok->isUnaryOp("*"))
return tok;
// Skip following variables if it is used in an assignment
if (Token::Match(tok->astParent(), "%assign%") || Token::Match(tok->next(), "%assign%"))
if (Token::Match(tok->astTop(), "%assign%") || Token::Match(tok->next(), "%assign%"))
return tok;
// Skip references
if (Token::Match(tok->astTop(), "& %var%;") && Token::Match(tok->astTop()->astOperand1(), "%type%"))
return tok;
const Variable * var = tok->variable();
const Token * varTok = getVariableInitExpression(var);
@ -199,6 +202,8 @@ static const Token * followVariableExpression(const Token * tok, bool cpp)
}
if (const Variable * var2 = tok2->variable()) {
if(!var2->scope())
return tok;
const Token * endToken2 = var2->scope() != tok->scope() ? var2->scope()->bodyEnd : endToken;
if (!var2->isLocal() && !var2->isConst() && !var2->isArgument())
return tok;

View File

@ -4546,6 +4546,32 @@ private:
" (void)b;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
// Issue #8712
check("void f() {\n"
" unsigned char d;\n"
" d = d % 5;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("template <typename T>\n"
"T f() {\n"
" T a = T();\n"
"}\n"
"int &a = f<int&>();\n");
ASSERT_EQUALS("", errout.str());
// Issue #8713
check("class A {\n"
" int64_t B = 32768;\n"
" P<uint8_t> m = MakeP<uint8_t>(B);\n"
"};\n"
"void f() {\n"
" uint32_t a = 42;\n"
" uint32_t b = uint32_t(A ::B / 1024);\n"
" int32_t c = int32_t(a / b);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void checkSignOfUnsignedVariable() {
@ -6829,6 +6855,14 @@ private:
" while (a=x(), a==123) {}\n"
"}", "test.c");
ASSERT_EQUALS("", errout.str());
// # 8717
check("void f(int argc, char *const argv[]) {\n"
" char **local_argv = safe_malloc(sizeof (*local_argv));\n"
" int local_argc = 0;\n"
" local_argv[local_argc++] = argv[0];\n"
"}\n", "test.c");
ASSERT_EQUALS("", errout.str());
}
void testEvaluationOrderSelfAssignment() {