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
This commit is contained in:
parent
2c8087e34f
commit
38aaa46804
|
@ -7060,7 +7060,7 @@ bool Tokenizer::simplifyRedundantParentheses()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(tok->previous(), "[(!*;{}] ( %var% )") &&
|
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
|
// We have "( var )", remove the parentheses
|
||||||
tok->deleteThis();
|
tok->deleteThis();
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
|
|
|
@ -381,19 +381,20 @@ static bool iscast(const Token *tok)
|
||||||
if (Token::Match(tok, "( (| typeof (") && Token::Match(tok->link(), ") %num%"))
|
if (Token::Match(tok, "( (| typeof (") && Token::Match(tok->link(), ") %num%"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
bool type = false;
|
||||||
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
|
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
|
||||||
if (tok2->link() && tok2->str() == "<")
|
if (tok2->link() && tok2->str() == "<")
|
||||||
tok2 = tok2->link()->next();
|
tok2 = tok2->link()->next();
|
||||||
|
|
||||||
if (tok2->str() == ")")
|
if (tok2->str() == ")")
|
||||||
return tok2->previous()->str() == "*" ||
|
return type || tok2->previous()->str() == "*" ||
|
||||||
(Token::Match(tok2, ") %any%") &&
|
(Token::Match(tok2, ") %any%") &&
|
||||||
(tok2->strAt(1) == "&" || (!tok2->next()->isOp() && !Token::Match(tok2->next(), "[[]);,?:.]"))));
|
(tok2->strAt(1) == "&" || (!tok2->next()->isOp() && !Token::Match(tok2->next(), "[[]);,?:.]"))));
|
||||||
if (!Token::Match(tok2, "%var%|*|&|::"))
|
if (!Token::Match(tok2, "%var%|*|&|::"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (tok2->isStandardType())
|
if (tok2->isStandardType())
|
||||||
return true;
|
type = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -550,7 +551,7 @@ static void compileMulDiv(Token *&tok, std::stack<Token*> &op, unsigned int dept
|
||||||
{
|
{
|
||||||
compilePointerToElem(tok, op, depth);
|
compilePointerToElem(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (Token::Match(tok, "[*/%]")) {
|
if (Token::Match(tok, "[/%]") || (tok->str() == "*" && !tok->astOperand1())) {
|
||||||
if (Token::Match(tok, "* [*,)]")) {
|
if (Token::Match(tok, "* [*,)]")) {
|
||||||
Token* tok2 = tok;
|
Token* tok2 = tok;
|
||||||
while (tok2->next() && tok2->str() == "*")
|
while (tok2->next() && tok2->str() == "*")
|
||||||
|
@ -566,9 +567,9 @@ static void compileMulDiv(Token *&tok, std::stack<Token*> &op, unsigned int dept
|
||||||
|
|
||||||
static void compileAddSub(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
static void compileAddSub(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
{
|
{
|
||||||
compileMulDiv(tok,op, depth);
|
compileMulDiv(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (Token::Match(tok, "+|-")) {
|
if (Token::Match(tok, "+|-") && !tok->astOperand1()) {
|
||||||
compileBinOp(tok, compileMulDiv, op, depth);
|
compileBinOp(tok, compileMulDiv, op, depth);
|
||||||
} else break;
|
} else break;
|
||||||
}
|
}
|
||||||
|
@ -576,7 +577,7 @@ static void compileAddSub(Token *&tok, std::stack<Token*> &op, unsigned int dept
|
||||||
|
|
||||||
static void compileShift(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
static void compileShift(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
{
|
{
|
||||||
compileAddSub(tok,op, depth);
|
compileAddSub(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (Token::Match(tok, "<<|>>")) {
|
if (Token::Match(tok, "<<|>>")) {
|
||||||
compileBinOp(tok, compileAddSub, op, depth);
|
compileBinOp(tok, compileAddSub, op, depth);
|
||||||
|
@ -586,7 +587,7 @@ static void compileShift(Token *&tok, std::stack<Token*> &op, unsigned int depth
|
||||||
|
|
||||||
static void compileRelComp(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
static void compileRelComp(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
{
|
{
|
||||||
compileShift(tok,op, depth);
|
compileShift(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (Token::Match(tok, "<|<=|>=|>")) {
|
if (Token::Match(tok, "<|<=|>=|>")) {
|
||||||
compileBinOp(tok, compileShift, op, depth);
|
compileBinOp(tok, compileShift, op, depth);
|
||||||
|
@ -596,7 +597,7 @@ static void compileRelComp(Token *&tok, std::stack<Token*> &op, unsigned int dep
|
||||||
|
|
||||||
static void compileEqComp(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
static void compileEqComp(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
{
|
{
|
||||||
compileRelComp(tok,op, depth);
|
compileRelComp(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (Token::Match(tok, "==|!=")) {
|
if (Token::Match(tok, "==|!=")) {
|
||||||
compileBinOp(tok, compileRelComp, op, depth);
|
compileBinOp(tok, compileRelComp, op, depth);
|
||||||
|
@ -606,9 +607,9 @@ static void compileEqComp(Token *&tok, std::stack<Token*> &op, unsigned int dept
|
||||||
|
|
||||||
static void compileAnd(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
static void compileAnd(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
{
|
{
|
||||||
compileEqComp(tok,op, depth);
|
compileEqComp(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (tok->str() == "&") {
|
if (tok->str() == "&" && !tok->astOperand1()) {
|
||||||
compileBinOp(tok, compileEqComp, op, depth);
|
compileBinOp(tok, compileEqComp, op, depth);
|
||||||
} else break;
|
} else break;
|
||||||
}
|
}
|
||||||
|
@ -616,7 +617,7 @@ static void compileAnd(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
|
|
||||||
static void compileXor(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
static void compileXor(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
{
|
{
|
||||||
compileAnd(tok,op, depth);
|
compileAnd(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (tok->str() == "^") {
|
if (tok->str() == "^") {
|
||||||
compileBinOp(tok, compileAnd, op, depth);
|
compileBinOp(tok, compileAnd, op, depth);
|
||||||
|
@ -626,7 +627,7 @@ static void compileXor(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
|
|
||||||
static void compileOr(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
static void compileOr(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
{
|
{
|
||||||
compileXor(tok,op, depth);
|
compileXor(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (tok->str() == "|") {
|
if (tok->str() == "|") {
|
||||||
compileBinOp(tok, compileXor, op, depth);
|
compileBinOp(tok, compileXor, op, depth);
|
||||||
|
@ -636,7 +637,7 @@ static void compileOr(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
|
|
||||||
static void compileLogicAnd(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
static void compileLogicAnd(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
{
|
{
|
||||||
compileOr(tok,op, depth);
|
compileOr(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (tok->str() == "&&") {
|
if (tok->str() == "&&") {
|
||||||
compileBinOp(tok, compileOr, op, depth);
|
compileBinOp(tok, compileOr, op, depth);
|
||||||
|
@ -646,7 +647,7 @@ static void compileLogicAnd(Token *&tok, std::stack<Token*> &op, unsigned int de
|
||||||
|
|
||||||
static void compileLogicOr(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
static void compileLogicOr(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
{
|
{
|
||||||
compileLogicAnd(tok,op, depth);
|
compileLogicAnd(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (tok->str() == "||") {
|
if (tok->str() == "||") {
|
||||||
compileBinOp(tok, compileLogicAnd, op, depth);
|
compileBinOp(tok, compileLogicAnd, op, depth);
|
||||||
|
|
|
@ -373,6 +373,7 @@ private:
|
||||||
TEST_CASE(removeParentheses18); // 'float(*a)[2]' => 'float *a[2]'
|
TEST_CASE(removeParentheses18); // 'float(*a)[2]' => 'float *a[2]'
|
||||||
TEST_CASE(removeParentheses19); // ((typeof(x) *)0)
|
TEST_CASE(removeParentheses19); // ((typeof(x) *)0)
|
||||||
TEST_CASE(removeParentheses20); // Ticket #5479: a<b<int>>(2);
|
TEST_CASE(removeParentheses20); // Ticket #5479: a<b<int>>(2);
|
||||||
|
TEST_CASE(removeParentheses21); // Don't "simplify" casts
|
||||||
|
|
||||||
TEST_CASE(tokenize_double);
|
TEST_CASE(tokenize_double);
|
||||||
TEST_CASE(tokenize_strings);
|
TEST_CASE(tokenize_strings);
|
||||||
|
@ -5696,6 +5697,10 @@ private:
|
||||||
ASSERT_EQUALS("a < b < int > > ( 2 ) ;", tokenizeAndStringify("a<b<int>>(2);", false));
|
ASSERT_EQUALS("a < b < int > > ( 2 ) ;", tokenizeAndStringify("a<b<int>>(2);", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeParentheses21() {
|
||||||
|
ASSERT_EQUALS("a = ( int ) - b ;", tokenizeAndStringify("a = ((int)-b);", false));
|
||||||
|
}
|
||||||
|
|
||||||
void tokenize_double() {
|
void tokenize_double() {
|
||||||
const char code[] = "void f()\n"
|
const char code[] = "void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -10595,6 +10600,8 @@ private:
|
||||||
ASSERT_EQUALS("ac*(=", testAst("a = (Foo*)*c;"));
|
ASSERT_EQUALS("ac*(=", testAst("a = (Foo*)*c;"));
|
||||||
ASSERT_EQUALS("ac-(=", testAst("a = (long)-c;"));
|
ASSERT_EQUALS("ac-(=", testAst("a = (long)-c;"));
|
||||||
ASSERT_EQUALS("ac(=", testAst("a = (some<strange, type>)c;"));
|
ASSERT_EQUALS("ac(=", testAst("a = (some<strange, type>)c;"));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("ab-(=", testAst("a = ((int)-b)")); // Multiple subsequent unary operators (cast and -)
|
||||||
}
|
}
|
||||||
|
|
||||||
void compileLimits() {
|
void compileLimits() {
|
||||||
|
|
Loading…
Reference in New Issue