AST: Refactored CheckOther::clarifyCalculation

This commit is contained in:
Daniel Marjamäki 2013-12-24 10:07:20 +01:00
parent 753559fff3
commit 4c44e62159
3 changed files with 19 additions and 43 deletions

View File

@ -179,50 +179,21 @@ void CheckOther::clarifyCalculation()
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i]; const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (tok->str() == "?") { // ? operator where lhs is arithmetical expression
// condition if (tok->str() != "?" || !tok->astOperand1() || !tok->astOperand1()->isArithmeticalOp())
const Token *cond = tok->previous();
if (cond->isName() || cond->isNumber())
cond = cond->previous();
else if (cond->str() == ")")
cond = cond->link()->previous();
else
continue; continue;
if (cond && cond->str() == "!") // Is code clarified by parentheses already?
cond = cond->previous(); const Token *tok2 = tok->astOperand1();
for (; tok2; tok2 = tok2->next()) {
if (!cond) if (tok2->str() == "(")
continue; tok2 = tok2->link();
else if (tok2->str() == ")" || tok2->str() == "?")
// calculation
if (!cond->isArithmeticalOp())
continue;
const std::string &op = cond->str();
cond = cond->previous();
// skip previous multiplications..
while (cond && cond->previous()) {
if ((cond->isName() || cond->isNumber()) && cond->previous()->str() == "*")
cond = cond->tokAt(-2);
else if (cond->str() == ")")
cond = cond->link()->previous();
else
break; break;
} }
if (!cond) if (tok2 && tok2->str() == "?")
continue; clarifyCalculationError(tok, tok->astOperand1()->str());
// first multiplication operand
if (cond->str() == ")") {
clarifyCalculationError(cond, op);
} else if (cond->isName() || cond->isNumber()) {
if (Token::Match(cond->previous(),"return|=|+|-|,|(") || cond->strAt(-1) == op)
clarifyCalculationError(cond, op);
}
}
} }
} }
} }

View File

@ -667,7 +667,7 @@ static void compileExpression(Token *&tok, std::stack<Token*> &op)
void TokenList::createAst() void TokenList::createAst()
{ {
for (Token *tok = _front; tok; tok = tok ? tok->next() : NULL) { for (Token *tok = _front; tok; tok = tok ? tok->next() : NULL) {
if (tok->str() == "return" || !tok->previous() || Token::Match(tok, "%var% (|[|.|=") || Token::Match(tok->previous(), "[;{}] %cop%")) { if (tok->str() == "return" || !tok->previous() || Token::Match(tok, "%var% (|[|.|=|::") || Token::Match(tok->previous(), "[;{}] %cop%")) {
std::stack<Token *> operands; std::stack<Token *> operands;
compileExpression(tok, operands); compileExpression(tok, operands);
} }

View File

@ -4138,6 +4138,11 @@ private:
"}"); "}");
ASSERT_EQUALS("[test.cpp:2]: (style) Clarify calculation precedence for '*' and '?'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Clarify calculation precedence for '*' and '?'.\n", errout.str());
check("void f() {\n"
" return (2*a)?b:c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// Ticket #2585 - segmentation fault for invalid code // Ticket #2585 - segmentation fault for invalid code
check("abcdef?""?<" check("abcdef?""?<"
"123456?""?>" "123456?""?>"