Fixed #6290 (Tokenizer: Because 'and' is not simplified to '&&' there are false positives)
This commit is contained in:
parent
d0ff8d87cb
commit
e3892a95b5
|
@ -6175,26 +6175,42 @@ static const std::map<std::string, std::string> cAlternativeTokens(cAlternativeT
|
|||
// xor_eq => ^=
|
||||
bool Tokenizer::simplifyCAlternativeTokens()
|
||||
{
|
||||
/* For C code: executable scope level */
|
||||
unsigned int executableScopeLevel = 0;
|
||||
|
||||
bool ret = false;
|
||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
Token *start = startOfExecutableScope(tok);
|
||||
if (start) { // Check for executable scope
|
||||
tok = start;
|
||||
Token * const end = tok->link();
|
||||
for (Token *tok2 = tok->next(); tok2 && tok2 != end; tok2 = tok2->next()) {
|
||||
if (Token::Match(tok2, "%var%|%num%|)|]|> %any% %var%|%num%|(|%op%")) {
|
||||
const std::map<std::string, std::string>::const_iterator cOpIt = cAlternativeTokens.find(tok2->next()->str());
|
||||
if (cOpIt != cAlternativeTokens.end()) {
|
||||
tok2->next()->str(cOpIt->second);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
if (Token::Match(tok2, "not|compl %var%|(|%op%") &&
|
||||
!Token::Match(tok2->previous(), "[;{}]")) { // Don't simplify 'not p;' (in case 'not' is a type)
|
||||
tok2->str((tok2->str() == "not") ? "!" : "~");
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
if (tok->str() == "{") {
|
||||
if (executableScopeLevel > 0 || Token::Match(tok->previous(), ") {"))
|
||||
++executableScopeLevel;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tok->str() == "}") {
|
||||
if (executableScopeLevel > 0)
|
||||
--executableScopeLevel;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!tok->isName())
|
||||
continue;
|
||||
|
||||
const std::map<std::string, std::string>::const_iterator cOpIt = cAlternativeTokens.find(tok->str());
|
||||
if (cOpIt != cAlternativeTokens.end()) {
|
||||
if (isC() && !Token::Match(tok->previous(), "%var%|%num%|%char%|)|]|> %var% %var%|%num%|%char%|%op%|("))
|
||||
continue;
|
||||
tok->str(cOpIt->second);
|
||||
ret = true;
|
||||
}
|
||||
else if (Token::Match(tok, "not|compl")) {
|
||||
// Don't simplify 'not p;' (in case 'not' is a type)
|
||||
if (isC() && (!Token::Match(tok->next(), "%var%|%op%|(") ||
|
||||
Token::Match(tok->previous(), "[;{}]") ||
|
||||
(executableScopeLevel == 0U && tok->strAt(-1) == "(")))
|
||||
continue;
|
||||
|
||||
tok->str((tok->str() == "not") ? "!" : "~");
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -316,7 +316,7 @@ private:
|
|||
return tokenizer.tokens()->stringifyList(0, !simplify);
|
||||
}
|
||||
|
||||
std::string tok(const char code[], const char filename[]) {
|
||||
std::string tok(const char code[], const char filename[], bool simplify = true) {
|
||||
errout.str("");
|
||||
|
||||
Settings settings;
|
||||
|
@ -324,7 +324,8 @@ private:
|
|||
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, filename);
|
||||
tokenizer.simplifyTokenList2();
|
||||
if (simplify)
|
||||
tokenizer.simplifyTokenList2();
|
||||
|
||||
return tokenizer.tokens()->stringifyList(0, false);
|
||||
}
|
||||
|
@ -1684,68 +1685,71 @@ private:
|
|||
}
|
||||
|
||||
void not1() {
|
||||
ASSERT_EQUALS("void f ( ) { if ( ! p ) { ; } }", tok("void f() { if (not p); }", false));
|
||||
ASSERT_EQUALS("void f ( ) { if ( p && ! q ) { ; } }", tok("void f() { if (p && not q); }", false));
|
||||
ASSERT_EQUALS("void f ( ) { a = ! ( p && q ) ; }", tok("void f() { a = not(p && q); }", false));
|
||||
ASSERT_EQUALS("void f ( ) { if ( ! p ) { ; } }", tok("void f() { if (not p); }", "test.c", false));
|
||||
ASSERT_EQUALS("void f ( ) { if ( p && ! q ) { ; } }", tok("void f() { if (p && not q); }", "test.c", false));
|
||||
ASSERT_EQUALS("void f ( ) { a = ! ( p && q ) ; }", tok("void f() { a = not(p && q); }", "test.c", false));
|
||||
// Don't simplify 'not' or 'compl' if they are defined as a type;
|
||||
// in variable declaration and in function declaration/definition
|
||||
ASSERT_EQUALS("struct not { int x ; } ;", tok("struct not { int x; };", false));
|
||||
ASSERT_EQUALS("void f ( ) { not p ; compl c ; }", tok(" void f() { not p; compl c; }", false));
|
||||
ASSERT_EQUALS("void foo ( not i ) ;", tok("void foo(not i);", false));
|
||||
ASSERT_EQUALS("int foo ( not i ) { return g ( i ) ; }", tok("int foo(not i) { return g(i); }", false));
|
||||
ASSERT_EQUALS("struct not { int x ; } ;", tok("struct not { int x; };", "test.c", false));
|
||||
ASSERT_EQUALS("void f ( ) { not p ; compl c ; }", tok(" void f() { not p; compl c; }", "test.c", false));
|
||||
ASSERT_EQUALS("void foo ( not i ) ;", tok("void foo(not i);", "test.c", false));
|
||||
ASSERT_EQUALS("int foo ( not i ) { return g ( i ) ; }", tok("int foo(not i) { return g(i); }", "test.c", false));
|
||||
}
|
||||
|
||||
void and1() {
|
||||
ASSERT_EQUALS("void f ( ) { if ( p && q ) { ; } }",
|
||||
tok("void f() { if (p and q) ; }", false));
|
||||
tok("void f() { if (p and q) ; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { if ( foo ( ) && q ) { ; } }",
|
||||
tok("void f() { if (foo() and q) ; }", false));
|
||||
tok("void f() { if (foo() and q) ; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { if ( foo ( ) && bar ( ) ) { ; } }",
|
||||
tok("void f() { if (foo() and bar()) ; }", false));
|
||||
tok("void f() { if (foo() and bar()) ; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { if ( p && bar ( ) ) { ; } }",
|
||||
tok("void f() { if (p and bar()) ; }", false));
|
||||
tok("void f() { if (p and bar()) ; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { if ( p && ! q ) { ; } }",
|
||||
tok("void f() { if (p and not q) ; }", false));
|
||||
tok("void f() { if (p and not q) ; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { r = a && b ; }",
|
||||
tok("void f() { r = a and b; }", false));
|
||||
tok("void f() { r = a and b; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { r = ( a || b ) && ( c || d ) ; }",
|
||||
tok("void f() { r = (a || b) and (c || d); }", false));
|
||||
tok("void f() { r = (a || b) and (c || d); }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { if ( test1 [ i ] == 'A' && test2 [ i ] == 'C' ) { } }",
|
||||
tok("void f() { if (test1[i] == 'A' and test2[i] == 'C') {} }", "test.c", false));
|
||||
}
|
||||
|
||||
void or1() {
|
||||
ASSERT_EQUALS("void f ( ) { if ( p || q ) { ; } }",
|
||||
tok("void f() { if (p or q) ; }", false));
|
||||
tok("void f() { if (p or q) ; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { if ( foo ( ) || q ) { ; } }",
|
||||
tok("void f() { if (foo() or q) ; }", false));
|
||||
tok("void f() { if (foo() or q) ; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { if ( foo ( ) || bar ( ) ) { ; } }",
|
||||
tok("void f() { if (foo() or bar()) ; }", false));
|
||||
tok("void f() { if (foo() or bar()) ; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { if ( p || bar ( ) ) { ; } }",
|
||||
tok("void f() { if (p or bar()) ; }", false));
|
||||
tok("void f() { if (p or bar()) ; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { if ( p || ! q ) { ; } }",
|
||||
tok("void f() { if (p or not q) ; }", false));
|
||||
tok("void f() { if (p or not q) ; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { r = a || b ; }",
|
||||
tok("void f() { r = a or b; }", false));
|
||||
tok("void f() { r = a or b; }", "test.c", false));
|
||||
|
||||
ASSERT_EQUALS("void f ( ) { r = ( a && b ) || ( c && d ) ; }",
|
||||
tok("void f() { r = (a && b) or (c && d); }", false));
|
||||
tok("void f() { r = (a && b) or (c && d); }", "test.c", false));
|
||||
}
|
||||
|
||||
void cAlternativeTokens() {
|
||||
ASSERT_EQUALS("void f ( ) { err = err | ( ( r & s ) && ! t ) ; }",
|
||||
tok("void f() { err or_eq ((r bitand s) and not t); }", false));
|
||||
tok("void f() { err or_eq ((r bitand s) and not t); }", "test.c", false));
|
||||
ASSERT_EQUALS("void f ( ) const { r = f ( a [ 4 ] | 15 , ~ c , ! d ) ; }",
|
||||
tok("void f() const { r = f(a[4] bitor 0x0F, compl c, not d) ; }", false));
|
||||
tok("void f() const { r = f(a[4] bitor 0x0F, compl c, not d) ; }", "test.c", false));
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue