Fixed #5406 (crash inside valueFlowBeforeCondition() on files from kernel-git)
This commit is contained in:
parent
2b8cf462c9
commit
c8a1424e10
|
@ -686,9 +686,8 @@ static void compileExpression(Token *&tok, std::stack<Token*> &op)
|
||||||
compileComma(tok,op);
|
compileComma(tok,op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TokenList::createAst()
|
static Token * createAstAtToken(Token *tok)
|
||||||
{
|
{
|
||||||
for (Token *tok = _front; tok; tok = tok ? tok->next() : NULL) {
|
|
||||||
if (Token::simpleMatch(tok,"for (")) {
|
if (Token::simpleMatch(tok,"for (")) {
|
||||||
Token *tok2 = tok->tokAt(2);
|
Token *tok2 = tok->tokAt(2);
|
||||||
Token *init1 = 0;
|
Token *init1 = 0;
|
||||||
|
@ -713,8 +712,7 @@ void TokenList::createAst()
|
||||||
tok->next()->astOperand2(init1);
|
tok->next()->astOperand2(init1);
|
||||||
tok->next()->astOperand1(tok);
|
tok->next()->astOperand1(tok);
|
||||||
}
|
}
|
||||||
tok = tok2;
|
return tok2;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Token * const init = init1 ? init1 : tok2;
|
Token * const init = init1 ? init1 : tok2;
|
||||||
|
@ -746,12 +744,34 @@ void TokenList::createAst()
|
||||||
tok->next()->astOperand1(tok);
|
tok->next()->astOperand1(tok);
|
||||||
tok->next()->astOperand2(semicolon1);
|
tok->next()->astOperand2(semicolon1);
|
||||||
|
|
||||||
tok = tok->linkAt(1);
|
return tok->linkAt(1);
|
||||||
}
|
}
|
||||||
if (tok->str() == "return" || !tok->previous() || Token::Match(tok, "%var% %op%|(|[|.|=|::") || Token::Match(tok->previous(), "[;{}] %cop%|(")) {
|
|
||||||
|
if (tok->str() == "return" || !tok->previous() || Token::Match(tok, "%var% %op%|(|[|.|=|::") || Token::Match(tok->previous(), "[;{}] %cop%|( !!{")) {
|
||||||
std::stack<Token *> operands;
|
std::stack<Token *> operands;
|
||||||
|
Token * const tok1 = tok;
|
||||||
compileExpression(tok, operands);
|
compileExpression(tok, operands);
|
||||||
|
Token * const endToken = tok;
|
||||||
|
|
||||||
|
// Compile inner expressions inside inner ({..})
|
||||||
|
for (tok = tok1; tok && tok != endToken; tok = tok ? tok->next() : NULL) {
|
||||||
|
if (!Token::simpleMatch(tok, "( {"))
|
||||||
|
continue;
|
||||||
|
const Token * const endToken2 = tok->linkAt(1);
|
||||||
|
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : NULL)
|
||||||
|
tok = createAstAtToken(tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return endToken ? endToken->previous() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TokenList::createAst()
|
||||||
|
{
|
||||||
|
for (Token *tok = _front; tok; tok = tok ? tok->next() : NULL) {
|
||||||
|
tok = createAstAtToken(tok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10065,13 +10065,18 @@ private:
|
||||||
// Create AST..
|
// Create AST..
|
||||||
tokenList.createAst();
|
tokenList.createAst();
|
||||||
|
|
||||||
|
// Return stringified AST
|
||||||
|
std::string ret;
|
||||||
|
std::set<const Token *> astTop;
|
||||||
for (const Token *tok = tokenList.front(); tok; tok = tok->next()) {
|
for (const Token *tok = tokenList.front(); tok; tok = tok->next()) {
|
||||||
if (tok->astOperand1())
|
if (tok->astOperand1() && astTop.find(tok->astTop()) == astTop.end()) {
|
||||||
return tok->astTop()->astString();
|
astTop.insert(tok->astTop());
|
||||||
|
if (!ret.empty())
|
||||||
|
ret = ret + " ";
|
||||||
|
ret += tok->astTop()->astString();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// No AST found
|
return ret;
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void astexpr() const { // simple expressions with arithmetical ops
|
void astexpr() const { // simple expressions with arithmetical ops
|
||||||
|
@ -10108,6 +10113,11 @@ private:
|
||||||
TODO_ASSERT_EQUALS("fori1=current0=,iNUM<=i++;;(", "fori1=current0=,i<NUM=i++;;(", testAst("for(i = (1), current = 0; i <= (NUM); ++i)"));
|
TODO_ASSERT_EQUALS("fori1=current0=,iNUM<=i++;;(", "fori1=current0=,i<NUM=i++;;(", testAst("for(i = (1), current = 0; i <= (NUM); ++i)"));
|
||||||
ASSERT_EQUALS("foreachxy,((", testAst("for(each(x,y)){}")); // it's not well-defined what this ast should be
|
ASSERT_EQUALS("foreachxy,((", testAst("for(each(x,y)){}")); // it's not well-defined what this ast should be
|
||||||
ASSERT_EQUALS("forab:(", testAst("for (int a : b);"));
|
ASSERT_EQUALS("forab:(", testAst("for (int a : b);"));
|
||||||
|
|
||||||
|
// problems with multiple expressions
|
||||||
|
ASSERT_EQUALS("ax( whilex(", testAst("a(x) while (x)"));
|
||||||
|
ASSERT_EQUALS("ifx( i0= whilei(", testAst("if (x) { ({ int i = 0; while(i); }) };"));
|
||||||
|
ASSERT_EQUALS("ifx( BUG_ON{!( i0= whilei(", testAst("if (x) { BUG_ON(!({int i=0; while(i);})); }"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void astpar() const { // parentheses
|
void astpar() const { // parentheses
|
||||||
|
@ -10126,8 +10136,8 @@ private:
|
||||||
ASSERT_EQUALS("ab::r&c(=", testAst("a::b& r = (a::b&)c;")); // #5261
|
ASSERT_EQUALS("ab::r&c(=", testAst("a::b& r = (a::b&)c;")); // #5261
|
||||||
|
|
||||||
// ({..})
|
// ({..})
|
||||||
ASSERT_EQUALS("a{+d+", testAst("a+({b+c;})+d"));
|
ASSERT_EQUALS("a{+d+ bc+", testAst("a+({b+c;})+d"));
|
||||||
ASSERT_EQUALS("a{d*+", testAst("a+({b+c;})*d"));
|
ASSERT_EQUALS("a{d*+ bc+", testAst("a+({b+c;})*d"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void astbrackets() const { // []
|
void astbrackets() const { // []
|
||||||
|
@ -10162,7 +10172,7 @@ private:
|
||||||
|
|
||||||
void asttemplate() const { // uninstantiated templates will have <,>,etc..
|
void asttemplate() const { // uninstantiated templates will have <,>,etc..
|
||||||
ASSERT_EQUALS("a(3==", testAst("a<int>()==3"));
|
ASSERT_EQUALS("a(3==", testAst("a<int>()==3"));
|
||||||
ASSERT_EQUALS("ab(==", testAst("a == b<c>(); f();"));
|
ASSERT_EQUALS("ab(== f(", testAst("a == b<c>(); f();"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue