* Fix #10809 cppcheckError Cyclic reverse analysis * Handle fixed AST in ValueFlow, fix FN * Remove
This commit is contained in:
parent
69116c8386
commit
d4705ca8ab
|
@ -560,9 +560,9 @@ static bool iscpp11init_impl(const Token * const tok)
|
|||
return true;
|
||||
if (nameToken->str() == ">" && nameToken->link())
|
||||
nameToken = nameToken->link()->previous();
|
||||
if (nameToken->str() == "]") {
|
||||
const Token* newTok = nameToken->link()->previous();
|
||||
while (Token::Match(newTok, "%type%|::") && !newTok->isKeyword())
|
||||
if (Token::Match(nameToken, "]|*")) {
|
||||
const Token* newTok = nameToken->link() ? nameToken->link()->previous() : nameToken->previous();
|
||||
while (Token::Match(newTok, "%type%|::|*") && !newTok->isKeyword())
|
||||
newTok = newTok->previous();
|
||||
if (Token::simpleMatch(newTok, "new"))
|
||||
return true;
|
||||
|
@ -880,8 +880,10 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
|
|||
{
|
||||
auto doCompileScope = [&](const Token* tok) -> bool {
|
||||
const bool isStartOfCpp11Init = state.cpp && tok && tok->str() == "{" && iscpp11init(tok);
|
||||
if (isStartOfCpp11Init) {
|
||||
if (isStartOfCpp11Init || Token::simpleMatch(tok, "(")) {
|
||||
tok = tok->previous();
|
||||
while (Token::simpleMatch(tok, "*"))
|
||||
tok = tok->previous();
|
||||
while (tok && Token::Match(tok->previous(), ":: %type%"))
|
||||
tok = tok->tokAt(-2);
|
||||
if (tok && !tok->isKeyword())
|
||||
|
@ -891,8 +893,11 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
|
|||
return !findLambdaEndTokenWithoutAST(tok);
|
||||
};
|
||||
|
||||
if (doCompileScope(tok))
|
||||
bool isNew = true;
|
||||
if (doCompileScope(tok)) {
|
||||
compileScope(tok, state);
|
||||
isNew = false;
|
||||
}
|
||||
while (tok) {
|
||||
if (tok->tokType() == Token::eIncDecOp && !isPrefixUnary(tok, state.cpp)) {
|
||||
compileUnaryOp(tok, state, compileScope);
|
||||
|
@ -982,7 +987,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
|
|||
const std::size_t oldOpSize = state.op.size();
|
||||
compileExpression(tok, state);
|
||||
tok = tok2;
|
||||
if ((oldOpSize > 0 && Token::simpleMatch(tok->previous(), "} ("))
|
||||
if ((oldOpSize > 0 && (isNew || Token::simpleMatch(tok->previous(), "} (")))
|
||||
|| (tok->previous() && tok->previous()->isName() && !Token::Match(tok->previous(), "return|case") && (!state.cpp || !Token::Match(tok->previous(), "throw|delete")))
|
||||
|| (tok->strAt(-1) == "]" && (!state.cpp || !Token::Match(tok->linkAt(-1)->previous(), "new|delete")))
|
||||
|| (tok->strAt(-1) == ">" && tok->linkAt(-1))
|
||||
|
|
|
@ -8941,17 +8941,14 @@ static void valueFlowDynamicBufferSize(const TokenList* tokenlist, const SymbolD
|
|||
const Token* bracTok = nullptr, *typeTok = nullptr;
|
||||
if (newTok->astOperand1()->str() == "[")
|
||||
bracTok = newTok->astOperand1();
|
||||
else if (newTok->astOperand1()->str() == "(") {
|
||||
else if (Token::Match(newTok->astOperand1(), "(|{")) {
|
||||
if (newTok->astOperand1()->astOperand1() && newTok->astOperand1()->astOperand1()->str() == "[")
|
||||
bracTok = newTok->astOperand1()->astOperand1();
|
||||
else
|
||||
typeTok = newTok->astOperand1()->astOperand1();
|
||||
}
|
||||
else {
|
||||
else
|
||||
typeTok = newTok->astOperand1();
|
||||
if (typeTok->str() == "{")
|
||||
typeTok = typeTok->astOperand1();
|
||||
}
|
||||
if (bracTok && bracTok->astOperand2() && bracTok->astOperand2()->hasKnownIntValue())
|
||||
numElem = bracTok->astOperand2()->getKnownIntValue();
|
||||
else if (Token::Match(typeTok, "%type%"))
|
||||
|
|
|
@ -2880,6 +2880,14 @@ private:
|
|||
" delete[] z;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'z[5]' accessed at index 7, which is out of bounds.\n", errout.str());
|
||||
|
||||
check("void h() {\n"
|
||||
" int** z = new int* [5]{ 0 };\n"
|
||||
" for (int n = 0; n < 8; ++n)\n"
|
||||
" z[n] = nullptr;\n"
|
||||
" delete[] z;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'z[5]' accessed at index 7, which is out of bounds.\n", errout.str());
|
||||
}
|
||||
|
||||
void buffer_overrun_2_struct() {
|
||||
|
|
|
@ -6178,6 +6178,10 @@ private:
|
|||
ASSERT_EQUALS("intnewdelete", testAst("void f() { delete new int; }"));
|
||||
ASSERT_EQUALS("pint3[new1+=", testAst("p = (new int[3]) + 1;")); // #11327
|
||||
ASSERT_EQUALS("aType2[T1T2,{new=", testAst("a = new Type *[2] {T1, T2};")); // #11745
|
||||
ASSERT_EQUALS("pSthis(new=", testAst("p = new S*(this);")); // #10809
|
||||
ASSERT_EQUALS("pint0{new=", testAst("p = new int*{ 0 };"));
|
||||
ASSERT_EQUALS("pint5[{new=", testAst("p = new int* [5]{};"));
|
||||
ASSERT_EQUALS("pint5[0{new=", testAst("p = new int* [5]{ 0 };"));
|
||||
|
||||
// placement new
|
||||
ASSERT_EQUALS("X12,3,(new ab,c,", testAst("new (a,b,c) X(1,2,3);"));
|
||||
|
|
Loading…
Reference in New Issue