diff --git a/lib/checkother.cpp b/lib/checkother.cpp index fca403df9..ddd78ef95 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -50,6 +50,8 @@ static bool isSameExpression(const Token *tok1, const Token *tok2, const std::se else if (tok1->function() && !tok1->function()->isConst) return false; } + if (Token::Match(tok1, "++|--")) + return false; if (!isSameExpression(tok1->astOperand1(), tok2->astOperand1(), constFunctions)) return false; if (!isSameExpression(tok1->astOperand2(), tok2->astOperand2(), constFunctions)) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 528171099..d139c1001 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -357,6 +357,21 @@ bool TokenList::createTokens(std::istream &code, const std::string& file0) //--------------------------------------------------------------------------- +static bool iscast(const Token *tok) +{ + if (!Token::Match(tok, "( %var%")) + return false; + + for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) { + if (tok2->str() == ")") + return (tok2->next() && !tok2->next()->isOp()); + if (!Token::Match(tok2, "%var%|*")) + return false; + } + + return false; +} + static void compileUnaryOp(Token *&tok, void (*f)(Token *&, std::stack &), std::stack &op) { Token *unaryop = tok; @@ -391,14 +406,19 @@ static void compileBinOp(Token *&tok, void (*f)(Token *&, std::stack &), op.push(binop); } +static void compileDot(Token *&tok, std::stack &op); static void compileExpression(Token *&tok, std::stack &op); static void compileTerm(Token *& tok, std::stack &op) { + if (!tok) + return; if (tok->isLiteral()) { op.push(tok); tok = tok->next(); - } else if (Token::Match(tok, "+|-|~|*|&|!|return")) { + } else if (Token::Match(tok, "+|-|~|*|&|!")) { + compileUnaryOp(tok, compileDot, op); + } else if (tok->str() == "return") { compileUnaryOp(tok, compileExpression, op); } else if (tok->isName()) { if (Token::Match(tok->next(), "++|--")) { // post increment / decrement @@ -435,13 +455,25 @@ static void compileTerm(Token *& tok, std::stack &op) tok = tok->next(); } else { // pre increment/decrement - compileUnaryOp(tok, compileExpression, op); + compileUnaryOp(tok, compileDot, op); } } else if (tok->str() == "(") { - // Parenthesized sub-expression - tok = tok->next(); - compileExpression(tok,op); - tok = tok->next(); + if (iscast(tok)) { + Token *unaryop = tok; + tok = tok->link()->next(); + compileDot(tok,op); + + if (!op.empty()) { + unaryop->astOperand1(op.top()); + op.pop(); + } + op.push(unaryop); + } else { + // Parenthesized sub-expression + tok = tok->next(); + compileExpression(tok,op); + tok = tok->next(); + } } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ed9a3d038..27f094c53 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -9961,6 +9961,8 @@ private: ASSERT_EQUALS("ab::c+", testAst("a::b+c")); ASSERT_EQUALS("abc+=", testAst("a=b+c")); ASSERT_EQUALS("abc=,", testAst("a,b=c")); + ASSERT_EQUALS("a-1+", testAst("-a+1")); + ASSERT_EQUALS("ab++-c-", testAst("a-b++-c")); ASSERT_EQUALS("a\"\"=", testAst("a=\"\"")); ASSERT_EQUALS("a\'\'=", testAst("a=\'\'")); @@ -9974,6 +9976,10 @@ private: ASSERT_EQUALS("123+*", testAst("1*(2+3)")); ASSERT_EQUALS("123+*4*", testAst("1*(2+3)*4")); ASSERT_EQUALS("ifab.c&d==(", testAst("if((a.b&c)==d){}")); + + // casts + ASSERT_EQUALS("a1(2(+=",testAst("a=(t)1+(t)2;")); + ASSERT_EQUALS("a1(2+=",testAst("a=(t)1+2;")); } void astbrackets() const { // []