diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 68186c60e..459a0f43e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4850,6 +4850,20 @@ bool Tokenizer::simplifyConditions() ret = true; } + else if (Token::simpleMatch(tok, "( true ||") || + Token::simpleMatch(tok, "( false &&")) + { + Token::eraseTokens(tok->next(), tok->link()); + ret = true; + } + + else if (Token::simpleMatch(tok, "|| true )") || + Token::simpleMatch(tok, "&& false )")) + { + Token::eraseTokens(tok->tokAt(2)->link(), tok->next()); + ret = true; + } + // Change numeric constant in condition to "true" or "false" if (Token::Match(tok, "if|while ( %num%") && (tok->tokAt(3)->str() == ")" || tok->tokAt(3)->str() == "||" || tok->tokAt(3)->str() == "&&")) @@ -6344,6 +6358,16 @@ bool Tokenizer::simplifyKnownVariables() ret = true; } + // condition "(|&&|%OROR% %varid% )|&&|%OROR% + if (!Token::Match(tok3->previous(), "( %var% )") && + (Token::Match(tok3->previous(), "&&|(") || tok3->strAt(-1) == "||") && + tok3->varId() == varid && + (Token::Match(tok3->next(), "&&|)") || tok3->strAt(1) == "||")) + { + tok3->str(value); + ret = true; + } + // Variable is used somehow in a non-defined pattern => bail out if (tok3->varId() == varid) { diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index f351cbaec..f57bde0f4 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -241,6 +241,7 @@ private: TEST_CASE(reverseArraySyntax) TEST_CASE(simplify_numeric_condition) + TEST_CASE(simplify_condition); TEST_CASE(pointeralias1); TEST_CASE(pointeralias2); @@ -5454,6 +5455,45 @@ private: } } + void simplify_condition() + { + { + const char code[] = + "void f(int a)\n" + "{\n" + "if (a && false) g();\n" + "}"; + ASSERT_EQUALS("void f ( int a ) { }", tok(code)); + } + + { + const char code[] = + "void f(int a)\n" + "{\n" + "if (false && a) g();\n" + "}"; + ASSERT_EQUALS("void f ( int a ) { }", tok(code)); + } + + { + const char code[] = + "void f(int a)\n" + "{\n" + "if (true || a) g();\n" + "}"; + ASSERT_EQUALS("void f ( int a ) { { g ( ) ; } }", tok(code)); + } + + { + const char code[] = + "void f(int a)\n" + "{\n" + "if (a || true) g();\n" + "}"; + ASSERT_EQUALS("void f ( int a ) { { g ( ) ; } }", tok(code)); + } + } + void pointeralias1() { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index b81c698fc..82460bbf6 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -126,6 +126,7 @@ private: TEST_CASE(simplifyKnownVariables35); // ticket #2353 - False positive: Division by zero 'if (x == 0) return 0; return 10 / x;' TEST_CASE(simplifyKnownVariables36); // ticket #2304 - known value for strcpy parameter TEST_CASE(simplifyKnownVariables37); // ticket #2398 - false positive caused by no simplification in for loop + TEST_CASE(simplifyKnownVariables38); // ticket #2399 - simplify conditions TEST_CASE(simplifyKnownVariablesBailOutAssign); TEST_CASE(simplifyKnownVariablesBailOutFor1); TEST_CASE(simplifyKnownVariablesBailOutFor2); @@ -1941,6 +1942,22 @@ private: ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); } + void simplifyKnownVariables38() + { + // Ticket #2399 - simplify conditions + const char code[] = "void f() {\n" + " int x = 0;\n" + " int y = 1;\n" + " if (x || y);\n" + "}"; + const char expected[] = "void f ( ) {\n" + ";\n" + "\n" + "{ ; }\n" + "}"; + ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); + } + void simplifyKnownVariablesBailOutAssign() { const char code[] = "int foo() {\n"