From 38aaa46804c606afaf66c4f4ad314177ac3a3a25 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Sat, 24 May 2014 19:04:47 +0200 Subject: [PATCH] Stabilized AST: - Fixed broken simplification causing crashs when cast was followed by unary minus (real world examples from arch/parisc/math-emu/ (linux-kernel)) - Stabilized determination of unary and binary operators --- lib/tokenize.cpp | 2 +- lib/tokenlist.cpp | 29 +++++++++++++++-------------- test/testtokenize.cpp | 7 +++++++ 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7d917eb6c..80c8a1763 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7060,7 +7060,7 @@ bool Tokenizer::simplifyRedundantParentheses() } if (Token::Match(tok->previous(), "[(!*;{}] ( %var% )") && - (tok->next()->varId() != 0 || Token::Match(tok->tokAt(3), "[+-/=]"))) { + (tok->next()->varId() != 0 || Token::Match(tok->tokAt(3), "[+-/=]")) && !tok->next()->isStandardType()) { // We have "( var )", remove the parentheses tok->deleteThis(); tok->deleteNext(); diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 24a1e9eb1..be05a2098 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -381,19 +381,20 @@ static bool iscast(const Token *tok) if (Token::Match(tok, "( (| typeof (") && Token::Match(tok->link(), ") %num%")) return true; + bool type = false; for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) { if (tok2->link() && tok2->str() == "<") tok2 = tok2->link()->next(); if (tok2->str() == ")") - return tok2->previous()->str() == "*" || + return type || tok2->previous()->str() == "*" || (Token::Match(tok2, ") %any%") && (tok2->strAt(1) == "&" || (!tok2->next()->isOp() && !Token::Match(tok2->next(), "[[]);,?:.]")))); if (!Token::Match(tok2, "%var%|*|&|::")) return false; if (tok2->isStandardType()) - return true; + type = true; } return false; @@ -550,7 +551,7 @@ static void compileMulDiv(Token *&tok, std::stack &op, unsigned int dept { compilePointerToElem(tok, op, depth); while (tok) { - if (Token::Match(tok, "[*/%]")) { + if (Token::Match(tok, "[/%]") || (tok->str() == "*" && !tok->astOperand1())) { if (Token::Match(tok, "* [*,)]")) { Token* tok2 = tok; while (tok2->next() && tok2->str() == "*") @@ -566,9 +567,9 @@ static void compileMulDiv(Token *&tok, std::stack &op, unsigned int dept static void compileAddSub(Token *&tok, std::stack &op, unsigned int depth) { - compileMulDiv(tok,op, depth); + compileMulDiv(tok, op, depth); while (tok) { - if (Token::Match(tok, "+|-")) { + if (Token::Match(tok, "+|-") && !tok->astOperand1()) { compileBinOp(tok, compileMulDiv, op, depth); } else break; } @@ -576,7 +577,7 @@ static void compileAddSub(Token *&tok, std::stack &op, unsigned int dept static void compileShift(Token *&tok, std::stack &op, unsigned int depth) { - compileAddSub(tok,op, depth); + compileAddSub(tok, op, depth); while (tok) { if (Token::Match(tok, "<<|>>")) { compileBinOp(tok, compileAddSub, op, depth); @@ -586,7 +587,7 @@ static void compileShift(Token *&tok, std::stack &op, unsigned int depth static void compileRelComp(Token *&tok, std::stack &op, unsigned int depth) { - compileShift(tok,op, depth); + compileShift(tok, op, depth); while (tok) { if (Token::Match(tok, "<|<=|>=|>")) { compileBinOp(tok, compileShift, op, depth); @@ -596,7 +597,7 @@ static void compileRelComp(Token *&tok, std::stack &op, unsigned int dep static void compileEqComp(Token *&tok, std::stack &op, unsigned int depth) { - compileRelComp(tok,op, depth); + compileRelComp(tok, op, depth); while (tok) { if (Token::Match(tok, "==|!=")) { compileBinOp(tok, compileRelComp, op, depth); @@ -606,9 +607,9 @@ static void compileEqComp(Token *&tok, std::stack &op, unsigned int dept static void compileAnd(Token *&tok, std::stack &op, unsigned int depth) { - compileEqComp(tok,op, depth); + compileEqComp(tok, op, depth); while (tok) { - if (tok->str() == "&") { + if (tok->str() == "&" && !tok->astOperand1()) { compileBinOp(tok, compileEqComp, op, depth); } else break; } @@ -616,7 +617,7 @@ static void compileAnd(Token *&tok, std::stack &op, unsigned int depth) static void compileXor(Token *&tok, std::stack &op, unsigned int depth) { - compileAnd(tok,op, depth); + compileAnd(tok, op, depth); while (tok) { if (tok->str() == "^") { compileBinOp(tok, compileAnd, op, depth); @@ -626,7 +627,7 @@ static void compileXor(Token *&tok, std::stack &op, unsigned int depth) static void compileOr(Token *&tok, std::stack &op, unsigned int depth) { - compileXor(tok,op, depth); + compileXor(tok, op, depth); while (tok) { if (tok->str() == "|") { compileBinOp(tok, compileXor, op, depth); @@ -636,7 +637,7 @@ static void compileOr(Token *&tok, std::stack &op, unsigned int depth) static void compileLogicAnd(Token *&tok, std::stack &op, unsigned int depth) { - compileOr(tok,op, depth); + compileOr(tok, op, depth); while (tok) { if (tok->str() == "&&") { compileBinOp(tok, compileOr, op, depth); @@ -646,7 +647,7 @@ static void compileLogicAnd(Token *&tok, std::stack &op, unsigned int de static void compileLogicOr(Token *&tok, std::stack &op, unsigned int depth) { - compileLogicAnd(tok,op, depth); + compileLogicAnd(tok, op, depth); while (tok) { if (tok->str() == "||") { compileBinOp(tok, compileLogicAnd, op, depth); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 112380456..eff722c54 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -373,6 +373,7 @@ private: TEST_CASE(removeParentheses18); // 'float(*a)[2]' => 'float *a[2]' TEST_CASE(removeParentheses19); // ((typeof(x) *)0) TEST_CASE(removeParentheses20); // Ticket #5479: a>(2); + TEST_CASE(removeParentheses21); // Don't "simplify" casts TEST_CASE(tokenize_double); TEST_CASE(tokenize_strings); @@ -5696,6 +5697,10 @@ private: ASSERT_EQUALS("a < b < int > > ( 2 ) ;", tokenizeAndStringify("a>(2);", false)); } + void removeParentheses21() { + ASSERT_EQUALS("a = ( int ) - b ;", tokenizeAndStringify("a = ((int)-b);", false)); + } + void tokenize_double() { const char code[] = "void f()\n" "{\n" @@ -10595,6 +10600,8 @@ private: ASSERT_EQUALS("ac*(=", testAst("a = (Foo*)*c;")); ASSERT_EQUALS("ac-(=", testAst("a = (long)-c;")); ASSERT_EQUALS("ac(=", testAst("a = (some)c;")); + + ASSERT_EQUALS("ab-(=", testAst("a = ((int)-b)")); // Multiple subsequent unary operators (cast and -) } void compileLimits() {