Fixed #4928 (C++ operator aliases result in false 'assigned a value that is never used' warning)
This commit is contained in:
parent
6fb4ce37fb
commit
9a08da17be
|
@ -1680,7 +1680,7 @@ bool Tokenizer::tokenizeCondition(const std::string &code)
|
||||||
while (TemplateSimplifier::simplifyNumericCalculations(tok))
|
while (TemplateSimplifier::simplifyNumericCalculations(tok))
|
||||||
;
|
;
|
||||||
|
|
||||||
while (simplifyLogicalOperators()) { }
|
simplifyCAlternativeTokens();
|
||||||
|
|
||||||
// Convert e.g. atol("0") into 0
|
// Convert e.g. atol("0") into 0
|
||||||
while (simplifyMathFunctions()) {};
|
while (simplifyMathFunctions()) {};
|
||||||
|
@ -3384,11 +3384,6 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
|
||||||
// simplify function pointers
|
// simplify function pointers
|
||||||
simplifyFunctionPointers();
|
simplifyFunctionPointers();
|
||||||
|
|
||||||
// "if (not p)" => "if (!p)"
|
|
||||||
// "if (p and q)" => "if (p && q)"
|
|
||||||
// "if (p or q)" => "if (p || q)"
|
|
||||||
while (simplifyLogicalOperators()) {}
|
|
||||||
|
|
||||||
// Change initialisation of variable to assignment
|
// Change initialisation of variable to assignment
|
||||||
simplifyInitVar();
|
simplifyInitVar();
|
||||||
|
|
||||||
|
@ -3402,6 +3397,9 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
|
||||||
setVarId();
|
setVarId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simplify the C alternative tokens (and, or, etc.)
|
||||||
|
simplifyCAlternativeTokens();
|
||||||
|
|
||||||
// The simplify enum might have inner loops
|
// The simplify enum might have inner loops
|
||||||
if (_settings->terminated())
|
if (_settings->terminated())
|
||||||
return false;
|
return false;
|
||||||
|
@ -6028,51 +6026,49 @@ void Tokenizer::simplifyIfSameInnerCondition()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Binary operators simplification map
|
||||||
|
static const std::pair<std::string, std::string> cAlternativeTokens_[] = {
|
||||||
|
std::make_pair("and", "&&"), std::make_pair("and_eq", "&="), std::make_pair("bitand", "&"),
|
||||||
|
std::make_pair("bitor", "|"), std::make_pair("not_eq", "!="), std::make_pair("or", "||"),
|
||||||
|
std::make_pair("or_eq", "|="), std::make_pair("xor", "^"), std::make_pair("xor_eq", "^=")
|
||||||
|
};
|
||||||
|
|
||||||
bool Tokenizer::simplifyLogicalOperators()
|
static const std::map<std::string, std::string> cAlternativeTokens(cAlternativeTokens_,
|
||||||
|
cAlternativeTokens_ + sizeof(cAlternativeTokens_)/sizeof(*cAlternativeTokens_));
|
||||||
|
|
||||||
|
// Simplify the C alternative tokens:
|
||||||
|
// and => &&
|
||||||
|
// and_eq => &=
|
||||||
|
// bitand => &
|
||||||
|
// bitor => |
|
||||||
|
// compl => ~
|
||||||
|
// not => !
|
||||||
|
// not_eq => !=
|
||||||
|
// or => ||
|
||||||
|
// or_eq => |=
|
||||||
|
// xor => ^
|
||||||
|
// xor_eq => ^=
|
||||||
|
bool Tokenizer::simplifyCAlternativeTokens()
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
// "if (not p)" => "if (!p)"
|
|
||||||
// "if (p and q)" => "if (p && q)"
|
|
||||||
// "if (p or q)" => "if (p || q)"
|
|
||||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||||
if (Token::Match(tok, "if|while ( not|compl %var%")) {
|
if (Token::Match(tok, ") const| {")) { // Check for executable scope
|
||||||
tok->tokAt(2)->str(tok->strAt(2) == "not" ? "!" : "~");
|
while (tok->str() != "{")
|
||||||
ret = true;
|
tok = tok->next();
|
||||||
} else if (Token::Match(tok, "&& not|compl %var%")) {
|
Token * const end = tok->link();
|
||||||
tok->next()->str(tok->next()->str() == "not" ? "!" : "~");
|
for (Token *tok2 = tok->next(); tok2 && tok2 != end; tok2 = tok2->next()) {
|
||||||
ret = true;
|
if (Token::Match(tok2, "%var%|%num%|)|] %any% %var%|%num%|(")) {
|
||||||
} else if (Token::Match(tok, "|| not|compl %var%")) {
|
const std::map<std::string, std::string>::const_iterator cOpIt = cAlternativeTokens.find(tok2->next()->str());
|
||||||
tok->next()->str(tok->next()->str() == "not" ? "!" : "~");
|
if (cOpIt != cAlternativeTokens.end()) {
|
||||||
ret = true;
|
tok2->next()->str(cOpIt->second);
|
||||||
}
|
ret = true;
|
||||||
// "%var%|) and %var%|("
|
}
|
||||||
else if (Token::Match(tok, "%var% %any%")) {
|
}
|
||||||
if (!Token::Match(tok, "and|or|bitand|bitor|xor|not_eq"))
|
if (Token::Match(tok2, "not|compl %var%|(") &&
|
||||||
continue;
|
!Token::Match(tok2->previous(), "[;{}]")) { // Don't simplify 'not p;' (in case 'not' is a type)
|
||||||
|
tok2->str(Token::Match(tok2, "not") ? "!" : "~");
|
||||||
const Token *tok2 = tok;
|
ret = true;
|
||||||
while (nullptr != (tok2 = tok2->previous())) {
|
}
|
||||||
if (tok2->str() == ")")
|
|
||||||
tok2 = tok2->link();
|
|
||||||
else if (Token::Match(tok2, "(|;|{|}"))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (tok2 && Token::Match(tok2->previous(), "if|while (")) {
|
|
||||||
if (tok->str() == "and")
|
|
||||||
tok->str("&&");
|
|
||||||
else if (tok->str() == "or")
|
|
||||||
tok->str("||");
|
|
||||||
else if (tok->str() == "bitand")
|
|
||||||
tok->str("&");
|
|
||||||
else if (tok->str() == "bitor")
|
|
||||||
tok->str("|");
|
|
||||||
else if (tok->str() == "xor")
|
|
||||||
tok->str("^");
|
|
||||||
else if (tok->str() == "not_eq")
|
|
||||||
tok->str("!=");
|
|
||||||
ret = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,13 +289,13 @@ public:
|
||||||
void simplifyIfSameInnerCondition();
|
void simplifyIfSameInnerCondition();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplify the "not" and "and" keywords to "!" and "&&"
|
* Simplify the 'C Alternative Tokens'
|
||||||
* accordingly.
|
|
||||||
* Examples:
|
* Examples:
|
||||||
* - "if (not p)" => "if (!p)"
|
* "if(s and t)" => "if(s && t)"
|
||||||
* - "if (p and q)" => "if (p && q)"
|
* "while((r bitand s) and not t)" => while((r & s) && !t)"
|
||||||
|
* "a and_eq b;" => "a &= b;"
|
||||||
*/
|
*/
|
||||||
bool simplifyLogicalOperators();
|
bool simplifyCAlternativeTokens();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplify comma into a semicolon when possible:
|
* Simplify comma into a semicolon when possible:
|
||||||
|
|
|
@ -170,6 +170,8 @@ private:
|
||||||
// Simplify "or" to "||"
|
// Simplify "or" to "||"
|
||||||
TEST_CASE(or1);
|
TEST_CASE(or1);
|
||||||
|
|
||||||
|
TEST_CASE(cAlternativeTokens);
|
||||||
|
|
||||||
TEST_CASE(comma_keyword);
|
TEST_CASE(comma_keyword);
|
||||||
TEST_CASE(remove_comma);
|
TEST_CASE(remove_comma);
|
||||||
|
|
||||||
|
@ -2695,45 +2697,70 @@ private:
|
||||||
ASSERT_EQUALS("if ( ! ( ! fclose ( fd ) ) ) { ; }", tok("if(!(fclose(fd) == 0));", false));
|
ASSERT_EQUALS("if ( ! ( ! fclose ( fd ) ) ) { ; }", tok("if(!(fclose(fd) == 0));", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void not1() {
|
void not1() {
|
||||||
ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (not p);", false));
|
ASSERT_EQUALS("void f ( ) { if ( ! p ) { ; } }", tok("void f() { if (not p); }", false));
|
||||||
ASSERT_EQUALS("if ( p && ! q ) { ; }", tok("if (p && not q);", false));
|
ASSERT_EQUALS("void f ( ) { if ( p && ! q ) { ; } }", tok("void f() { if (p && not q); }", false));
|
||||||
ASSERT_EQUALS("void foo ( not i )", tok("void foo ( not i )", false));
|
ASSERT_EQUALS("void f ( ) { a = ! ( p && q ) ; }", tok("void f() { a = not(p && q); }", 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
void and1() {
|
void and1() {
|
||||||
ASSERT_EQUALS("if ( p && q ) { ; }",
|
ASSERT_EQUALS("void f ( ) { if ( p && q ) { ; } }",
|
||||||
tok("if (p and q) ;", false));
|
tok("void f() { if (p and q) ; }", false));
|
||||||
|
|
||||||
ASSERT_EQUALS("if ( foo ( ) && q ) { ; }",
|
ASSERT_EQUALS("void f ( ) { if ( foo ( ) && q ) { ; } }",
|
||||||
tok("if (foo() and q) ;", false));
|
tok("void f() { if (foo() and q) ; }", false));
|
||||||
|
|
||||||
ASSERT_EQUALS("if ( foo ( ) && bar ( ) ) { ; }",
|
ASSERT_EQUALS("void f ( ) { if ( foo ( ) && bar ( ) ) { ; } }",
|
||||||
tok("if (foo() and bar()) ;", false));
|
tok("void f() { if (foo() and bar()) ; }", false));
|
||||||
|
|
||||||
ASSERT_EQUALS("if ( p && bar ( ) ) { ; }",
|
ASSERT_EQUALS("void f ( ) { if ( p && bar ( ) ) { ; } }",
|
||||||
tok("if (p and bar()) ;", false));
|
tok("void f() { if (p and bar()) ; }", false));
|
||||||
|
|
||||||
ASSERT_EQUALS("if ( p && ! q ) { ; }",
|
ASSERT_EQUALS("void f ( ) { if ( p && ! q ) { ; } }",
|
||||||
tok("if (p and not q) ;", false));
|
tok("void f() { if (p and not q) ; }", false));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("void f ( ) { r = a && b ; }",
|
||||||
|
tok("void f() { r = a and b; }", false));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("void f ( ) { r = ( a || b ) && ( c || d ) ; }",
|
||||||
|
tok("void f() { r = (a || b) and (c || d); }", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
void or1() {
|
void or1() {
|
||||||
ASSERT_EQUALS("if ( p || q ) { ; }",
|
ASSERT_EQUALS("void f ( ) { if ( p || q ) { ; } }",
|
||||||
tok("if (p or q) ;", false));
|
tok("void f() { if (p or q) ; }", false));
|
||||||
|
|
||||||
ASSERT_EQUALS("if ( foo ( ) || q ) { ; }",
|
ASSERT_EQUALS("void f ( ) { if ( foo ( ) || q ) { ; } }",
|
||||||
tok("if (foo() or q) ;", false));
|
tok("void f() { if (foo() or q) ; }", false));
|
||||||
|
|
||||||
ASSERT_EQUALS("if ( foo ( ) || bar ( ) ) { ; }",
|
ASSERT_EQUALS("void f ( ) { if ( foo ( ) || bar ( ) ) { ; } }",
|
||||||
tok("if (foo() or bar()) ;", false));
|
tok("void f() { if (foo() or bar()) ; }", false));
|
||||||
|
|
||||||
ASSERT_EQUALS("if ( p || bar ( ) ) { ; }",
|
ASSERT_EQUALS("void f ( ) { if ( p || bar ( ) ) { ; } }",
|
||||||
tok("if (p or bar()) ;", false));
|
tok("void f() { if (p or bar()) ; }", false));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("void f ( ) { if ( p || ! q ) { ; } }",
|
||||||
|
tok("void f() { if (p or not q) ; }", false));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("void f ( ) { r = a || b ; }",
|
||||||
|
tok("void f() { r = a or b; }", false));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("void f ( ) { r = ( a && b ) || ( c && d ) ; }",
|
||||||
|
tok("void f() { r = (a && b) or (c && d); }", false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cAlternativeTokens() {
|
||||||
|
ASSERT_EQUALS("void f ( ) { err |= ( ( r & s ) && ! t ) ; }",
|
||||||
|
tok("void f() { err or_eq ((r bitand s) and not t); }", 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));
|
||||||
|
|
||||||
ASSERT_EQUALS("if ( p || ! q ) { ; }",
|
|
||||||
tok("if (p or not q) ;", false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void comma_keyword() {
|
void comma_keyword() {
|
||||||
|
|
|
@ -477,7 +477,7 @@ private:
|
||||||
|
|
||||||
TEST_CASE(simplifySQL);
|
TEST_CASE(simplifySQL);
|
||||||
|
|
||||||
TEST_CASE(simplifyLogicalOperators);
|
TEST_CASE(simplifyCAlternativeTokens);
|
||||||
|
|
||||||
TEST_CASE(simplifyCalculations);
|
TEST_CASE(simplifyCalculations);
|
||||||
|
|
||||||
|
@ -7811,15 +7811,15 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplifyLogicalOperators() {
|
void simplifyCAlternativeTokens() {
|
||||||
ASSERT_EQUALS("if ( a && b ) { ; }", tokenizeAndStringify("if (a and b);"));
|
ASSERT_EQUALS("void f ( ) { if ( a && b ) { ; } }", tokenizeAndStringify("void f() { if (a and b); }"));
|
||||||
ASSERT_EQUALS("if ( a || b ) { ; }", tokenizeAndStringify("if (a or b);"));
|
ASSERT_EQUALS("void f ( ) { if ( a || b ) { ; } }", tokenizeAndStringify("void f() { if (a or b); }"));
|
||||||
ASSERT_EQUALS("if ( a & b ) { ; }", tokenizeAndStringify("if (a bitand b);"));
|
ASSERT_EQUALS("void f ( ) { if ( a & b ) { ; } }", tokenizeAndStringify("void f() { if (a bitand b); }"));
|
||||||
ASSERT_EQUALS("if ( a | b ) { ; }", tokenizeAndStringify("if (a bitor b);"));
|
ASSERT_EQUALS("void f ( ) { if ( a | b ) { ; } }", tokenizeAndStringify("void f() { if (a bitor b); }"));
|
||||||
ASSERT_EQUALS("if ( a ^ b ) { ; }", tokenizeAndStringify("if (a xor b);"));
|
ASSERT_EQUALS("void f ( ) { if ( a ^ b ) { ; } }", tokenizeAndStringify("void f() { if (a xor b); }"));
|
||||||
ASSERT_EQUALS("if ( ~ b ) { ; }", tokenizeAndStringify("if (compl b);"));
|
ASSERT_EQUALS("void f ( ) { if ( ~ b ) { ; } }", tokenizeAndStringify("void f() { if (compl b); }"));
|
||||||
ASSERT_EQUALS("if ( ! b ) { ; }", tokenizeAndStringify("if (not b);"));
|
ASSERT_EQUALS("void f ( ) { if ( ! b ) { ; } }", tokenizeAndStringify("void f() { if (not b); }"));
|
||||||
ASSERT_EQUALS("if ( a != b ) { ; }", tokenizeAndStringify("if (a not_eq b);"));
|
ASSERT_EQUALS("void f ( ) { if ( a != b ) { ; } }", tokenizeAndStringify("void f() { if (a not_eq b); }"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplifyCalculations() {
|
void simplifyCalculations() {
|
||||||
|
|
Loading…
Reference in New Issue