Tokenizer: Removed Tokenizer::simplifyConditionOperator(). Using the AST and ValueFlow, it should be much easier to parse ?: than before.

This commit is contained in:
Daniel Marjamäki 2014-06-10 19:30:13 +02:00
parent 4daf775fe1
commit a4a6f3e1be
4 changed files with 1 additions and 162 deletions

View File

@ -3436,9 +3436,6 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
// syntax is corrected.
TemplateSimplifier::cleanupAfterSimplify(list.front());
// Simplify the operator "?:"
simplifyConditionOperator();
// Collapse operator name tokens into single token
// operator = => operator=
simplifyOperatorName();
@ -3670,8 +3667,6 @@ bool Tokenizer::simplifyTokenList2()
modified |= simplifyCalculations();
}
simplifyConditionOperator();
// simplify redundant for
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 ret = false;

View File

@ -386,11 +386,6 @@ public:
/** Simplify "if else" */
void elseif();
/**
* Simplify the operator "?:"
*/
void simplifyConditionOperator();
/** Simplify conditions
* @return true if something is modified
* false if nothing is done.

View File

@ -3001,11 +3001,6 @@ private:
}
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)";
ASSERT_EQUALS("( 3 )", tok(code));
@ -3081,51 +3076,9 @@ private:
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)
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)
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("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() {

View File

@ -1603,7 +1603,7 @@ private:
" int 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
{