More robust checking for crashes in followVar (#1375)

More robust checking for crashes in followVar
This commit is contained in:
Paul Fultz II 2018-09-13 02:19:15 -05:00 committed by PKEuS
parent eb07280075
commit 4e7ed9ea6e
2 changed files with 9 additions and 6 deletions

View File

@ -174,10 +174,7 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const
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->astTop(), "%assign%") || Token::Match(tok->next(), "%assign%")) if (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);
@ -197,7 +194,7 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const
const Token * lastTok = precedes(tok, end) ? end : tok; const Token * lastTok = precedes(tok, end) ? end : tok;
// If this is in a loop then check if variables are modified in the entire scope // If this is in a loop then check if variables are modified in the entire scope
const Token * endToken = (isInLoopCondition(tok) || isInLoopCondition(varTok) || var->scope() != tok->scope()) ? var->scope()->bodyEnd : lastTok; const Token * endToken = (isInLoopCondition(tok) || isInLoopCondition(varTok) || var->scope() != tok->scope()) ? var->scope()->bodyEnd : lastTok;
if (!var->isConst() && isVariableChanged(varTok, endToken, tok->varId(), false, nullptr, cpp)) if (!var->isConst() && (!precedes(varTok, endToken) || isVariableChanged(varTok, endToken, tok->varId(), false, nullptr, cpp)))
return tok; return tok;
// Start at beginning of initialization // Start at beginning of initialization
const Token * startToken = varTok; const Token * startToken = varTok;
@ -223,7 +220,7 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const
return tok; return tok;
if (var2->isStatic() && !var2->isConst()) if (var2->isStatic() && !var2->isConst())
return tok; return tok;
if (!var2->isConst() && isVariableChanged(tok2, endToken2, tok2->varId(), false, nullptr, cpp)) if (!var2->isConst() && (!precedes(tok2, endToken2) || isVariableChanged(tok2, endToken2, tok2->varId(), false, nullptr, cpp)))
return tok; return tok;
// Recognized as a variable but the declaration is unknown // Recognized as a variable but the declaration is unknown
} else if (tok2->varId() > 0) { } else if (tok2->varId() > 0) {

View File

@ -229,6 +229,7 @@ private:
TEST_CASE(garbageCode196); // #8265 TEST_CASE(garbageCode196); // #8265
TEST_CASE(garbageCode197); // #8385 TEST_CASE(garbageCode197); // #8385
TEST_CASE(garbageCode198); // #8383 TEST_CASE(garbageCode198); // #8383
TEST_CASE(garbageCode199); // #8752
TEST_CASE(garbageCodeFuzzerClientMode1); // test cases created with the fuzzer client, mode 1 TEST_CASE(garbageCodeFuzzerClientMode1); // test cases created with the fuzzer client, mode 1
@ -1540,6 +1541,11 @@ private:
"}"), InternalError); "}"), InternalError);
} }
// #8752
void garbageCode199() {
checkCode("d f(){e n00e0[]n00e0&""0+f=0}");
}
void syntaxErrorFirstToken() { void syntaxErrorFirstToken() {
ASSERT_THROW(checkCode("&operator(){[]};"), InternalError); // #7818 ASSERT_THROW(checkCode("&operator(){[]};"), InternalError); // #7818
ASSERT_THROW(checkCode("*(*const<> (size_t); foo) { } *(*const (size_t)() ; foo) { }"), InternalError); // #6858 ASSERT_THROW(checkCode("*(*const<> (size_t); foo) { } *(*const (size_t)() ; foo) { }"), InternalError); // #6858