Tokenizer: Removed Tokenizer::simplifyConditionOperator(). Using the AST and ValueFlow, it should be much easier to parse ?: than before.
This commit is contained in:
parent
4daf775fe1
commit
a4a6f3e1be
104
lib/tokenize.cpp
104
lib/tokenize.cpp
|
@ -3436,9 +3436,6 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
|
||||||
// syntax is corrected.
|
// syntax is corrected.
|
||||||
TemplateSimplifier::cleanupAfterSimplify(list.front());
|
TemplateSimplifier::cleanupAfterSimplify(list.front());
|
||||||
|
|
||||||
// Simplify the operator "?:"
|
|
||||||
simplifyConditionOperator();
|
|
||||||
|
|
||||||
// Collapse operator name tokens into single token
|
// Collapse operator name tokens into single token
|
||||||
// operator = => operator=
|
// operator = => operator=
|
||||||
simplifyOperatorName();
|
simplifyOperatorName();
|
||||||
|
@ -3670,8 +3667,6 @@ bool Tokenizer::simplifyTokenList2()
|
||||||
modified |= simplifyCalculations();
|
modified |= simplifyCalculations();
|
||||||
}
|
}
|
||||||
|
|
||||||
simplifyConditionOperator();
|
|
||||||
|
|
||||||
// simplify redundant for
|
// simplify redundant for
|
||||||
removeRedundantFor();
|
removeRedundantFor();
|
||||||
|
|
||||||
|
@ -4469,105 +4464,6 @@ void Tokenizer::simplifyCompoundAssignment()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tokenizer::simplifyConditionOperator()
|
|
||||||
{
|
|
||||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
|
||||||
if (tok->str() == "(" || tok->str() == "[" ||
|
|
||||||
(tok->str() == "{" && tok->previous() && tok->previous()->str() == "="))
|
|
||||||
tok = tok->link();
|
|
||||||
|
|
||||||
if (Token::Match(tok, "[{};] *| %var% = %any% ? %any% : %any% ;") ||
|
|
||||||
Token::Match(tok, "[{};] return %any% ? %any% : %any% ;")) {
|
|
||||||
|
|
||||||
// backup varids so they can be set properly
|
|
||||||
std::map<std::string, unsigned int> varid;
|
|
||||||
for (const Token *tok2 = tok->next(); tok2->str() != ";"; tok2 = tok2->next()) {
|
|
||||||
if (tok2->varId())
|
|
||||||
varid[tok2->str()] = tok2->varId();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string var(tok->next()->str());
|
|
||||||
bool isPointer = false;
|
|
||||||
bool isReturn = false;
|
|
||||||
if (tok->next()->str() == "*") {
|
|
||||||
tok = tok->next();
|
|
||||||
var = tok->next()->str();
|
|
||||||
isPointer = true;
|
|
||||||
} else if (tok->next()->str() == "return") {
|
|
||||||
isReturn = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token *tok2 = tok->tokAt(3 - (isReturn ? 1 : 0));
|
|
||||||
if (!tok2->isName() && !tok2->isNumber() && tok2->str()[0] != '\"')
|
|
||||||
continue;
|
|
||||||
const std::string condition(tok2->str());
|
|
||||||
tok2 = tok2->tokAt(2);
|
|
||||||
if (!tok2->isName() && !tok2->isNumber() && tok2->str()[0] != '\"')
|
|
||||||
continue;
|
|
||||||
const std::string value1(tok2->str());
|
|
||||||
tok2 = tok2->tokAt(2);
|
|
||||||
if (!tok2->isName() && !tok2->isNumber() && tok2->str()[0] != '\"')
|
|
||||||
continue;
|
|
||||||
const std::string value2(tok2->str());
|
|
||||||
|
|
||||||
if (isPointer) {
|
|
||||||
tok = tok->previous();
|
|
||||||
tok->deleteNext(9);
|
|
||||||
} else if (isReturn)
|
|
||||||
tok->deleteNext(6);
|
|
||||||
else
|
|
||||||
tok->deleteNext(8);
|
|
||||||
|
|
||||||
Token *starttok = nullptr;
|
|
||||||
|
|
||||||
std::string str;
|
|
||||||
if (isReturn)
|
|
||||||
str = "if ( condition ) { return value1 ; } return value2 ;";
|
|
||||||
else
|
|
||||||
str = "if ( condition ) { * var = value1 ; } else { * var = value2 ; }";
|
|
||||||
|
|
||||||
std::string::size_type pos1 = 0;
|
|
||||||
while (pos1 != std::string::npos) {
|
|
||||||
if (str[pos1] == '*') {
|
|
||||||
pos1 += 2;
|
|
||||||
if (isPointer) {
|
|
||||||
tok->insertToken("*");
|
|
||||||
tok = tok->next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string::size_type pos2 = str.find(" ", pos1);
|
|
||||||
if (pos2 == std::string::npos) {
|
|
||||||
tok->insertToken(str.substr(pos1));
|
|
||||||
pos1 = pos2;
|
|
||||||
} else {
|
|
||||||
tok->insertToken(str.substr(pos1, pos2 - pos1));
|
|
||||||
pos1 = pos2 + 1;
|
|
||||||
}
|
|
||||||
tok = tok->next();
|
|
||||||
|
|
||||||
// set links.
|
|
||||||
if (tok->str() == "(" || tok->str() == "{")
|
|
||||||
starttok = tok;
|
|
||||||
else if (starttok && (tok->str() == ")" || tok->str() == "}")) {
|
|
||||||
Token::createMutualLinks(starttok, tok);
|
|
||||||
starttok = 0;
|
|
||||||
} else if (tok->str() == "condition")
|
|
||||||
tok->str(condition);
|
|
||||||
else if (tok->str() == "var")
|
|
||||||
tok->str(var);
|
|
||||||
else if (tok->str() == "value1")
|
|
||||||
tok->str(value1);
|
|
||||||
else if (tok->str() == "value2")
|
|
||||||
tok->str(value2);
|
|
||||||
|
|
||||||
// set varid.
|
|
||||||
if (varid.find(tok->str()) != varid.end())
|
|
||||||
tok->varId(varid[tok->str()]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Tokenizer::simplifyConditions()
|
bool Tokenizer::simplifyConditions()
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
|
@ -386,11 +386,6 @@ public:
|
||||||
/** Simplify "if else" */
|
/** Simplify "if else" */
|
||||||
void elseif();
|
void elseif();
|
||||||
|
|
||||||
/**
|
|
||||||
* Simplify the operator "?:"
|
|
||||||
*/
|
|
||||||
void simplifyConditionOperator();
|
|
||||||
|
|
||||||
/** Simplify conditions
|
/** Simplify conditions
|
||||||
* @return true if something is modified
|
* @return true if something is modified
|
||||||
* false if nothing is done.
|
* false if nothing is done.
|
||||||
|
|
|
@ -3001,11 +3001,6 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplifyConditionOperator() {
|
void simplifyConditionOperator() {
|
||||||
{
|
|
||||||
const char code[] = "; x = a ? b : c;";
|
|
||||||
ASSERT_EQUALS("; if ( a ) { x = b ; } else { x = c ; }", tok(code));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const char code[] = "(0?(false?1:2):3)";
|
const char code[] = "(0?(false?1:2):3)";
|
||||||
ASSERT_EQUALS("( 3 )", tok(code));
|
ASSERT_EQUALS("( 3 )", tok(code));
|
||||||
|
@ -3081,51 +3076,9 @@ private:
|
||||||
ASSERT_EQUALS("; a = 1 ; b = 2 ;", tok(code));
|
ASSERT_EQUALS("; a = 1 ; b = 2 ;", tok(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
const char code[] = "int f(int b, int d)\n"
|
|
||||||
"{\n"
|
|
||||||
" d = b ? b : 10;\n"
|
|
||||||
" return d;\n"
|
|
||||||
"}\n";
|
|
||||||
ASSERT_EQUALS("int f ( int b , int d ) { if ( b ) { d = b ; } else { d = 10 ; } return d ; }", tok(code));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const char code[] = "int f(int b, int *d)\n"
|
|
||||||
"{\n"
|
|
||||||
" *d = b ? b : 10;\n"
|
|
||||||
" return *d;\n"
|
|
||||||
"}\n";
|
|
||||||
ASSERT_EQUALS("int f ( int b , int * d ) { if ( b ) { * d = b ; } else { * d = 10 ; } return * d ; }", tok(code));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const char code[] = "int f(int b, int *d)\n"
|
|
||||||
"{\n"
|
|
||||||
" if(b) {b++;}"
|
|
||||||
" *d = b ? b : 10;\n"
|
|
||||||
" return *d;\n"
|
|
||||||
"}\n";
|
|
||||||
ASSERT_EQUALS("int f ( int b , int * d ) { if ( b ) { b ++ ; } if ( b ) { * d = b ; } else { * d = 10 ; } return * d ; }", tok(code));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Ticket #2885
|
|
||||||
const char code[] = "; const char *cx16 = has_cmpxchg16b ? \" -mcx16\" : \" -mno-cx16\";";
|
|
||||||
const char expected[] = "; const char * cx16 ; if ( has_cmpxchg16b ) { cx16 = \" -mcx16\" ; } else { cx16 = \" -mno-cx16\" ; }";
|
|
||||||
ASSERT_EQUALS(expected, tok(code));
|
|
||||||
}
|
|
||||||
// Ticket #3572 (segmentation fault)
|
// Ticket #3572 (segmentation fault)
|
||||||
ASSERT_EQUALS("0 ; x = { ? y : z ; }", tok("0; x = { ? y : z; }"));
|
ASSERT_EQUALS("0 ; x = { ? y : z ; }", tok("0; x = { ? y : z; }"));
|
||||||
|
|
||||||
{
|
|
||||||
// #4019 - varid
|
|
||||||
const char code[] = "; char *p; *p = a ? 1 : 0;";
|
|
||||||
const char expected[] = "\n\n##file 0\n"
|
|
||||||
"1: ; char * p@1 ; if ( a ) { * p@1 = 1 ; } else { * p@1 = 0 ; }\n";
|
|
||||||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// #3922 - (true)
|
// #3922 - (true)
|
||||||
ASSERT_EQUALS("; x = 2 ;", tok("; x = (true)?2:4;"));
|
ASSERT_EQUALS("; x = 2 ;", tok("; x = (true)?2:4;"));
|
||||||
|
@ -3134,11 +3087,6 @@ private:
|
||||||
ASSERT_EQUALS("; x = * b ;", tok("; x = (false)?*a:*b;"));
|
ASSERT_EQUALS("; x = * b ;", tok("; x = (false)?*a:*b;"));
|
||||||
ASSERT_EQUALS("void f ( ) { return 1 ; }", tok("void f() { char *p=0; return (p==0)?1:2; }"));
|
ASSERT_EQUALS("void f ( ) { return 1 ; }", tok("void f() { char *p=0; return (p==0)?1:2; }"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4225 - varid gets lost
|
|
||||||
ASSERT_EQUALS("\n\n##file 0\n"
|
|
||||||
"1: int a@1 ; int b@2 ; int c@3 ; int d@4 ; if ( b@2 ) { a@1 = c@3 ; } else { a@1 = d@4 ; }\n",
|
|
||||||
tokenizeDebugListing("int a, b, c, d; a = b ? (int *)c : d;", true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculations() {
|
void calculations() {
|
||||||
|
|
|
@ -1603,7 +1603,7 @@ private:
|
||||||
" int y;\n"
|
" int y;\n"
|
||||||
" return x ? 1 : y;\n"
|
" return x ? 1 : y;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: y\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: y\n", errout.str());
|
||||||
|
|
||||||
// Ticket #3106 - False positive
|
// Ticket #3106 - False positive
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue