Fix crashes in followVarExpression (#1358)
* Fix crashes in followVarExpression * Add a regression test for issue 8717 * Skip reference declarations
This commit is contained in:
parent
215bc3b303
commit
8353f94b93
|
@ -163,7 +163,10 @@ static const Token * followVariableExpression(const Token * tok, bool cpp)
|
||||||
if (tok->astParent() && tok->isUnaryOp("*"))
|
if (tok->astParent() && tok->isUnaryOp("*"))
|
||||||
return tok;
|
return tok;
|
||||||
// Skip following variables if it is used in an assignment
|
// 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;
|
return tok;
|
||||||
const Variable * var = tok->variable();
|
const Variable * var = tok->variable();
|
||||||
const Token * varTok = getVariableInitExpression(var);
|
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 (const Variable * var2 = tok2->variable()) {
|
||||||
|
if(!var2->scope())
|
||||||
|
return tok;
|
||||||
const Token * endToken2 = var2->scope() != tok->scope() ? var2->scope()->bodyEnd : endToken;
|
const Token * endToken2 = var2->scope() != tok->scope() ? var2->scope()->bodyEnd : endToken;
|
||||||
if (!var2->isLocal() && !var2->isConst() && !var2->isArgument())
|
if (!var2->isLocal() && !var2->isConst() && !var2->isArgument())
|
||||||
return tok;
|
return tok;
|
||||||
|
|
|
@ -4546,6 +4546,32 @@ private:
|
||||||
" (void)b;\n"
|
" (void)b;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void checkSignOfUnsignedVariable() {
|
||||||
|
@ -6829,6 +6855,14 @@ private:
|
||||||
" while (a=x(), a==123) {}\n"
|
" while (a=x(), a==123) {}\n"
|
||||||
"}", "test.c");
|
"}", "test.c");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void testEvaluationOrderSelfAssignment() {
|
||||||
|
|
Loading…
Reference in New Issue