Fix 10435: False positive: containerOutOfBounds (#3426)
This commit is contained in:
parent
2ee880752f
commit
92eb59981d
|
@ -2533,3 +2533,51 @@ bool TokenImpl::getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, M
|
|||
*value = attr->value;
|
||||
return attr != nullptr;
|
||||
}
|
||||
|
||||
Token* findTypeEnd(Token* tok)
|
||||
{
|
||||
while (Token::Match(tok, "%name%|.|::|*|&|&&|<|(|template|decltype|sizeof")) {
|
||||
if (Token::Match(tok, "(|<"))
|
||||
tok = tok->link();
|
||||
if (!tok)
|
||||
return nullptr;
|
||||
tok = tok->next();
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
|
||||
const Token* findTypeEnd(const Token* tok) {
|
||||
return findTypeEnd(const_cast<Token*>(tok));
|
||||
}
|
||||
|
||||
Token* findLambdaEndScope(Token* tok)
|
||||
{
|
||||
if (!Token::simpleMatch(tok, "["))
|
||||
return nullptr;
|
||||
tok = tok->link();
|
||||
if (!Token::Match(tok, "] (|{"))
|
||||
return nullptr;
|
||||
tok = tok->linkAt(1);
|
||||
if (Token::simpleMatch(tok, "}"))
|
||||
return tok;
|
||||
if (Token::simpleMatch(tok, ") {"))
|
||||
return tok->linkAt(1);
|
||||
if (!Token::simpleMatch(tok, ")"))
|
||||
return nullptr;
|
||||
tok = tok->next();
|
||||
while (Token::Match(tok, "mutable|constexpr|constval|noexcept|.")) {
|
||||
if (Token::simpleMatch(tok, "noexcept ("))
|
||||
tok = tok->linkAt(1);
|
||||
if (Token::simpleMatch(tok, ".")) {
|
||||
tok = findTypeEnd(tok);
|
||||
break;
|
||||
}
|
||||
tok = tok->next();
|
||||
}
|
||||
if (Token::simpleMatch(tok, "{"))
|
||||
return tok->link();
|
||||
return nullptr;
|
||||
}
|
||||
const Token* findLambdaEndScope(const Token* tok) {
|
||||
return findLambdaEndScope(const_cast<Token*>(tok));
|
||||
}
|
||||
|
|
|
@ -1395,6 +1395,11 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
Token* findTypeEnd(Token* tok);
|
||||
const Token* findTypeEnd(const Token* tok);
|
||||
Token* findLambdaEndScope(Token* tok);
|
||||
const Token* findLambdaEndScope(const Token* tok);
|
||||
|
||||
/// @}
|
||||
//---------------------------------------------------------------------------
|
||||
#endif // tokenH
|
||||
|
|
|
@ -7239,8 +7239,34 @@ void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, co
|
|||
// Split up variable declarations..
|
||||
// "int a=4;" => "int a; a=4;"
|
||||
bool finishedwithkr = true;
|
||||
bool scopeDecl = false;
|
||||
for (Token *tok = tokBegin; tok != tokEnd; tok = tok->next()) {
|
||||
if (Token::simpleMatch(tok, "= {")) {
|
||||
if (Token::Match(tok, "{|;"))
|
||||
scopeDecl = false;
|
||||
if (isCPP()) {
|
||||
if (Token::Match(tok, "class|struct|namespace|union"))
|
||||
scopeDecl = true;
|
||||
if (Token::Match(tok, "decltype|noexcept (")) {
|
||||
tok = tok->next()->link();
|
||||
// skip decltype(...){...}
|
||||
if (tok && Token::simpleMatch(tok->previous(), ") {"))
|
||||
tok = tok->link();
|
||||
} else if (Token::simpleMatch(tok, "= {") ||
|
||||
(!scopeDecl && Token::Match(tok, "%name%|> {") &&
|
||||
!Token::Match(tok, "else|try|do|const|constexpr|override|volatile|noexcept"))) {
|
||||
if (!tok->next()->link())
|
||||
syntaxError(tokBegin);
|
||||
// Check for lambdas before skipping
|
||||
for (Token* tok2 = tok->next(); tok2 != tok->next()->link(); tok2 = tok2->next()) {
|
||||
Token* lambdaEnd = findLambdaEndScope(tok2);
|
||||
if (!lambdaEnd)
|
||||
continue;
|
||||
simplifyVarDecl(lambdaEnd->link()->next(), lambdaEnd, only_k_r_fpar);
|
||||
}
|
||||
tok = tok->next()->link();
|
||||
}
|
||||
|
||||
} else if (Token::simpleMatch(tok, "= {")) {
|
||||
tok = tok->next()->link();
|
||||
}
|
||||
if (!tok) {
|
||||
|
|
|
@ -560,52 +560,6 @@ static bool iscast(const Token *tok, bool cpp)
|
|||
return false;
|
||||
}
|
||||
|
||||
static Token* findTypeEnd(Token* tok)
|
||||
{
|
||||
while (Token::Match(tok, "%name%|.|::|*|&|&&|<|(|template|decltype|sizeof")) {
|
||||
if (Token::Match(tok, "(|<"))
|
||||
tok = tok->link();
|
||||
if (!tok)
|
||||
return nullptr;
|
||||
tok = tok->next();
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
|
||||
static const Token* findTypeEnd(const Token* tok)
|
||||
{
|
||||
return findTypeEnd(const_cast<Token*>(tok));
|
||||
}
|
||||
|
||||
static const Token * findLambdaEndScope(const Token *tok)
|
||||
{
|
||||
if (!Token::simpleMatch(tok, "["))
|
||||
return nullptr;
|
||||
tok = tok->link();
|
||||
if (!Token::Match(tok, "] (|{"))
|
||||
return nullptr;
|
||||
tok = tok->linkAt(1);
|
||||
if (Token::simpleMatch(tok, "}"))
|
||||
return tok;
|
||||
if (Token::simpleMatch(tok, ") {"))
|
||||
return tok->linkAt(1);
|
||||
if (!Token::simpleMatch(tok, ")"))
|
||||
return nullptr;
|
||||
tok = tok->next();
|
||||
while (Token::Match(tok, "mutable|constexpr|constval|noexcept|.")) {
|
||||
if (Token::simpleMatch(tok, "noexcept ("))
|
||||
tok = tok->linkAt(1);
|
||||
if (Token::simpleMatch(tok, ".")) {
|
||||
tok = findTypeEnd(tok);
|
||||
break;
|
||||
}
|
||||
tok = tok->next();
|
||||
}
|
||||
if (Token::simpleMatch(tok, "{"))
|
||||
return tok->link();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// int(1), int*(2), ..
|
||||
static Token * findCppTypeInitPar(Token *tok)
|
||||
{
|
||||
|
|
|
@ -367,7 +367,7 @@ private:
|
|||
TEST_CASE(simplify_constants4);
|
||||
TEST_CASE(simplify_constants5);
|
||||
TEST_CASE(simplify_constants6); // Ticket #5625: Ternary operator as template parameter
|
||||
|
||||
TEST_CASE(simplifyVarDeclInitLists);
|
||||
}
|
||||
|
||||
std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native) {
|
||||
|
@ -7063,6 +7063,13 @@ private:
|
|||
ASSERT_EQUALS(exp, tok(code));
|
||||
}
|
||||
}
|
||||
|
||||
void simplifyVarDeclInitLists()
|
||||
{
|
||||
const char code[] = "std::vector<int> v{a * b, 1};";
|
||||
const char exp[] = "std :: vector < int > v { a * b , 1 } ;";
|
||||
ASSERT_EQUALS(exp, tok(code));
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestSimplifyTokens)
|
||||
|
|
Loading…
Reference in New Issue