Skip to content

Commit

Permalink
Revert "Fix #404: simplecpp::TokenList::constFold does not fold '( 0 …
Browse files Browse the repository at this point in the history
…) && 10 < X' properly (#405)" (#416)
  • Loading branch information
danmar authored Feb 12, 2025
1 parent 9ce981c commit 09a8163
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 92 deletions.
98 changes: 34 additions & 64 deletions simplecpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ void simplecpp::TokenList::constFold()
constFoldQuestionOp(&tok);

// If there is no '(' we are done with the constant folding
if (!tok || tok->op != '(')
if (tok->op != '(')
break;

if (!tok->next || !tok->next->next || tok->next->next->op != ')')
Expand Down Expand Up @@ -1157,7 +1157,10 @@ void simplecpp::TokenList::constFoldMulDivRem(Token *tok)
} else
continue;

simpleSquash(tok, toString(result));
tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
}
}

Expand All @@ -1177,7 +1180,10 @@ void simplecpp::TokenList::constFoldAddSub(Token *tok)
else
continue;

simpleSquash(tok, toString(result));
tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
}
}

Expand All @@ -1197,7 +1203,10 @@ void simplecpp::TokenList::constFoldShift(Token *tok)
else
continue;

simpleSquash(tok, toString(result));
tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
}
}

Expand Down Expand Up @@ -1231,7 +1240,10 @@ void simplecpp::TokenList::constFoldComparison(Token *tok)
else
continue;

simpleSquash(tok, toString(result));
tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
}
}

Expand Down Expand Up @@ -1263,51 +1275,12 @@ void simplecpp::TokenList::constFoldBitwise(Token *tok)
result = (stringToLL(tok->previous->str()) ^ stringToLL(tok->next->str()));
else /*if (*op == '|')*/
result = (stringToLL(tok->previous->str()) | stringToLL(tok->next->str()));
simpleSquash(tok, toString(result));
}
}
}

void simplecpp::TokenList::simpleSquash(Token *&tok, const std::string & result)
{
tok = tok->previous;
tok->setstr(result);
deleteToken(tok->next);
deleteToken(tok->next);
}

void simplecpp::TokenList::squashTokens(Token *&tok, const std::set<std::string> & breakPoints, bool forwardDirection, const std::string & result)
{
const char * const brackets = forwardDirection ? "()" : ")(";
Token* Token::* const step = forwardDirection ? &Token::next : &Token::previous;
int skip = 0;
const Token * const tok1 = tok->*step;
while (tok1 && tok1->*step) {
if ((tok1->*step)->op == brackets[1]){
if (skip) {
--skip;
deleteToken(tok1->*step);
} else
break;
} else if ((tok1->*step)->op == brackets[0]) {
++skip;
deleteToken(tok1->*step);
} else if (skip) {
deleteToken(tok1->*step);
} else if (breakPoints.count((tok1->*step)->str()) != 0) {
break;
} else {
deleteToken(tok1->*step);
tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
}
}
simpleSquash(tok, result);
}

static simplecpp::Token * constFoldGetOperand(simplecpp::Token * tok, bool forwardDirection)
{
simplecpp::Token* simplecpp::Token::* const step = forwardDirection ? &simplecpp::Token::next : &simplecpp::Token::previous;
const char bracket = forwardDirection ? ')' : '(';
return tok->*step && (tok->*step)->number && (!((tok->*step)->*step) || (((tok->*step)->*step)->op == bracket)) ? tok->*step : nullptr;
}

static const std::string AND("and");
Expand All @@ -1323,24 +1296,21 @@ void simplecpp::TokenList::constFoldLogicalOp(Token *tok)
}
if (tok->str() != "&&" && tok->str() != "||")
continue;
const Token* const lhs = constFoldGetOperand(tok, false);
const Token* const rhs = constFoldGetOperand(tok, true);
if (!lhs) // if lhs is not a single number we don't need to fold
if (!tok->previous || !tok->previous->number)
continue;
if (!tok->next || !tok->next->number)
continue;

std::set<std::string> breakPoints;
breakPoints.insert(":");
breakPoints.insert("?");
if (tok->str() == "||"){
if (stringToLL(lhs->str()) != 0LL || (rhs && stringToLL(rhs->str()) != 0LL))
squashTokens(tok, breakPoints, stringToLL(lhs->str()) != 0LL, toString(1));
} else /*if (tok->str() == "&&")*/ {
breakPoints.insert("||");
if (stringToLL(lhs->str()) == 0LL || (rhs && stringToLL(rhs->str()) == 0LL))
squashTokens(tok, breakPoints, stringToLL(lhs->str()) == 0LL, toString(0));
else if (rhs && stringToLL(lhs->str()) && stringToLL(rhs->str()))
simpleSquash(tok, "1");
}
int result;
if (tok->str() == "||")
result = (stringToLL(tok->previous->str()) || stringToLL(tok->next->str()));
else /*if (tok->str() == "&&")*/
result = (stringToLL(tok->previous->str()) && stringToLL(tok->next->str()));

tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
}
}

Expand Down
2 changes: 0 additions & 2 deletions simplecpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,6 @@ namespace simplecpp {
void constFoldLogicalOp(Token *tok);
void constFoldQuestionOp(Token **tok1);

void simpleSquash(Token *&tok, const std::string & result);
void squashTokens(Token *&tok, const std::set<std::string> & breakPoints, bool forwardDirection, const std::string & result);
std::string readUntil(Stream &stream, const Location &location, char start, char end, OutputList *outputList);
void lineDirective(unsigned int fileIndex, unsigned int line, Location *location);

Expand Down
26 changes: 0 additions & 26 deletions test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,15 +452,6 @@ static void constFold()
ASSERT_EQUALS("1", testConstFold("010==8"));
ASSERT_EQUALS("exception", testConstFold("!1 ? 2 :"));
ASSERT_EQUALS("exception", testConstFold("?2:3"));
ASSERT_EQUALS("0", testConstFold("( 0 ) && 10 < X"));
ASSERT_EQUALS("0", testConstFold("1+2*(3+4) && 7 - 7"));
ASSERT_EQUALS("1", testConstFold("( 1 ) || 10 < X"));
ASSERT_EQUALS("1", testConstFold("1+2*(3+4) || 8 - 7"));
ASSERT_EQUALS("X && 0", testConstFold("X && 0"));
ASSERT_EQUALS("X >= 0 || 0 < Y", testConstFold("X >= 0 || 0 < Y"));
ASSERT_EQUALS("X && 1 && Z", testConstFold("X && (1 || Y) && Z"));
ASSERT_EQUALS("0 || Y", testConstFold("0 && X || Y"));
ASSERT_EQUALS("X > 0 && Y", testConstFold("X > 0 && Y"));
}

#ifdef __CYGWIN__
Expand Down Expand Up @@ -1617,22 +1608,6 @@ static void ifA()
ASSERT_EQUALS("\nX", preprocess(code, dui));
}

static void ifXorY()
{
const char code[] = "#if Z > 0 || 0 < Y\n"
"X\n"
"#endif";
ASSERT_EQUALS("", preprocess(code));

simplecpp::DUI dui;
dui.defines.push_back("Z=1");
ASSERT_EQUALS("\nX", preprocess(code, dui));

dui.defines.clear();
dui.defines.push_back("Y=15");
ASSERT_EQUALS("\nX", preprocess(code, dui));
}

static void ifCharLiteral()
{
const char code[] = "#if ('A'==0x41)\n"
Expand Down Expand Up @@ -3151,7 +3126,6 @@ int main(int argc, char **argv)
TEST_CASE(ifdef2);
TEST_CASE(ifndef);
TEST_CASE(ifA);
TEST_CASE(ifXorY);
TEST_CASE(ifCharLiteral);
TEST_CASE(ifDefined);
TEST_CASE(ifDefinedNoPar);
Expand Down

0 comments on commit 09a8163

Please sign in to comment.