Refactorized simplification of sizeof without parantheses:
- Moved sizeofAddParentheses() behind combineOperators() - Improved sizeofAddParentheses() to handle all code from unit tests at simplifyTokenList1() - Removed simplification from simplifyTokenList2()
This commit is contained in:
parent
4c40664861
commit
708a379fd2
116
lib/tokenize.cpp
116
lib/tokenize.cpp
|
@ -2974,25 +2974,22 @@ void Tokenizer::createLinks2()
|
|||
void Tokenizer::sizeofAddParentheses()
|
||||
{
|
||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
if (Token::Match(tok, "sizeof %name%|%num%|%str%")) {
|
||||
Token *endToken = tok->next();
|
||||
while (Token::Match(endToken, "%name%|%num%|%str%|[|(|.|::|++|--|!|~")) {
|
||||
if (endToken->str() == "[" || endToken->str() == "(")
|
||||
endToken = endToken->link();
|
||||
endToken = endToken->next();
|
||||
if (Token::simpleMatch(endToken, "- >"))
|
||||
endToken = endToken->tokAt(2);
|
||||
Token* next = tok->next();
|
||||
if (Token::Match(tok, "sizeof !!(") && next && (next->isLiteral() || next->isName() || Token::Match(next, "[*~!]"))) {
|
||||
Token *endToken = next;
|
||||
while (Token::Match(endToken->next(), "%name%|%num%|%str%|[|(|.|::|++|--|!|~") || (Token::Match(endToken, "%type% * %op%|?|:|const|;|,"))) {
|
||||
if (endToken->strAt(1) == "[" || endToken->strAt(1) == "(")
|
||||
endToken = endToken->linkAt(1);
|
||||
else
|
||||
endToken = endToken->next();
|
||||
}
|
||||
|
||||
if (endToken) {
|
||||
// Ok. Add ( after sizeof and ) before endToken
|
||||
tok->insertToken("(");
|
||||
endToken->previous()->insertToken(")");
|
||||
Token::createMutualLinks(tok->next(), endToken->previous());
|
||||
}
|
||||
// Add ( after sizeof and ) behind endToken
|
||||
tok->insertToken("(");
|
||||
endToken->insertToken(")");
|
||||
Token::createMutualLinks(tok->next(), endToken->next());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Tokenizer::simplifySizeof()
|
||||
|
@ -3059,16 +3056,6 @@ bool Tokenizer::simplifySizeof()
|
|||
tok->deleteNext(3);
|
||||
}
|
||||
|
||||
// sizeof 'x'
|
||||
if (tok->next()->type() == Token::eChar) {
|
||||
tok->deleteThis();
|
||||
std::ostringstream sz;
|
||||
sz << sizeof 'x';
|
||||
tok->str(sz.str());
|
||||
ret = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// sizeof('x')
|
||||
if (Token::Match(tok, "sizeof ( %char% )")) {
|
||||
tok->deleteNext();
|
||||
|
@ -3081,16 +3068,6 @@ bool Tokenizer::simplifySizeof()
|
|||
continue;
|
||||
}
|
||||
|
||||
// sizeof "text"
|
||||
if (tok->next()->type() == Token::eString) {
|
||||
tok->deleteThis();
|
||||
std::ostringstream ostr;
|
||||
ostr << (Token::getStrLength(tok) + 1);
|
||||
tok->str(ostr.str());
|
||||
ret = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// sizeof ("text")
|
||||
if (Token::Match(tok->next(), "( %str% )")) {
|
||||
tok->deleteNext();
|
||||
|
@ -3103,71 +3080,6 @@ bool Tokenizer::simplifySizeof()
|
|||
continue;
|
||||
}
|
||||
|
||||
// sizeof * (...) -> sizeof(*...)
|
||||
if (Token::simpleMatch(tok->next(), "* (") && !Token::simpleMatch(tok->linkAt(2), ") .")) {
|
||||
tok->deleteNext();
|
||||
tok->next()->insertToken("*");
|
||||
}
|
||||
|
||||
// sizeof a++ -> sizeof(a++)
|
||||
if (Token::Match(tok->next(), "++|-- %name% !!.") || Token::Match(tok->next(), "%name% ++|--")) {
|
||||
tok->insertToken("(");
|
||||
tok->tokAt(3)->insertToken(")");
|
||||
Token::createMutualLinks(tok->next(), tok->tokAt(4));
|
||||
}
|
||||
|
||||
// sizeof 1 => sizeof ( 1 )
|
||||
if (tok->next()->isNumber()) {
|
||||
Token *tok2 = tok->next();
|
||||
tok->insertToken("(");
|
||||
tok2->insertToken(")");
|
||||
Token::createMutualLinks(tok->next(), tok2->next());
|
||||
}
|
||||
|
||||
// sizeof int -> sizeof( int )
|
||||
else if (tok->next()->str() != "(") {
|
||||
// Add parentheses around the sizeof
|
||||
int parlevel = 0;
|
||||
for (Token *tempToken = tok->next(); tempToken; tempToken = tempToken->next()) {
|
||||
if (tempToken->str() == "(")
|
||||
++parlevel;
|
||||
else if (tempToken->str() == ")") {
|
||||
--parlevel;
|
||||
if (parlevel == 0 && !Token::Match(tempToken, ") . %name%")) {
|
||||
// Ok, we should be clean. Add ) after tempToken
|
||||
tok->insertToken("(");
|
||||
tempToken->insertToken(")");
|
||||
Token::createMutualLinks(tok->next(), tempToken->next());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (parlevel == 0 && Token::Match(tempToken, "%name%")) {
|
||||
while (tempToken && tempToken->next() && tempToken->next()->str() == "[") {
|
||||
tempToken = tempToken->next()->link();
|
||||
}
|
||||
if (!tempToken || !tempToken->next()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (tempToken->next()->str() == ".") {
|
||||
// We are checking a class or struct, search next varname
|
||||
tempToken = tempToken->next();
|
||||
continue;
|
||||
} else if (tempToken->next()->type() == Token::eIncDecOp) {
|
||||
// We have variable++ or variable--, there should be
|
||||
// nothing after this
|
||||
tempToken = tempToken->tokAt(2);
|
||||
}
|
||||
|
||||
// Ok, we should be clean. Add ) after tempToken
|
||||
tok->insertToken("(");
|
||||
tempToken->insertToken(")");
|
||||
Token::createMutualLinks(tok->next(), tempToken->next());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sizeof(type *) => sizeof(*)
|
||||
if (Token::Match(tok->next(), "( %type% * )")) {
|
||||
tok->next()->deleteNext();
|
||||
|
@ -3332,11 +3244,11 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
|
|||
if (!simplifyAddBraces())
|
||||
return false;
|
||||
|
||||
sizeofAddParentheses();
|
||||
|
||||
// Combine tokens..
|
||||
combineOperators();
|
||||
|
||||
sizeofAddParentheses();
|
||||
|
||||
// Simplify: 0[foo] -> *(foo)
|
||||
for (Token* tok = list.front(); tok; tok = tok->next()) {
|
||||
if (Token::simpleMatch(tok, "0 [") && tok->linkAt(1)) {
|
||||
|
|
|
@ -72,7 +72,8 @@ private:
|
|||
TEST_CASE(garbageCode31); // #6539
|
||||
TEST_CASE(garbageCode32); // #6135
|
||||
TEST_CASE(garbageCode33); // #6613
|
||||
TEST_CASE(garbageCode34); // 6626
|
||||
TEST_CASE(garbageCode34); // #6626
|
||||
TEST_CASE(garbageCode35); // #2599, #2604
|
||||
|
||||
TEST_CASE(garbageValueFlow);
|
||||
TEST_CASE(garbageSymbolDatabase);
|
||||
|
@ -242,7 +243,7 @@ private:
|
|||
}
|
||||
|
||||
void garbageCode7() {
|
||||
ASSERT_THROW(checkCode("1 (int j) { return return (c) * sizeof } y[1];"), InternalError);
|
||||
checkCode("1 (int j) { return return (c) * sizeof } y[1];");
|
||||
checkCode("foo(Args&&...) fn void = { } auto template<typename... bar(Args&&...)");
|
||||
}
|
||||
|
||||
|
@ -420,6 +421,14 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void garbageCode35() {
|
||||
// ticket #2599 segmentation fault
|
||||
checkCode("sizeof");
|
||||
|
||||
// ticket #2604 segmentation fault
|
||||
checkCode("sizeof <= A");
|
||||
}
|
||||
|
||||
void garbageValueFlow() {
|
||||
// #6089
|
||||
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"
|
||||
|
|
|
@ -79,8 +79,6 @@ private:
|
|||
TEST_CASE(sizeof19); // #1891 - sizeof 'x'
|
||||
TEST_CASE(sizeof20); // #2024 - sizeof a)
|
||||
TEST_CASE(sizeof21); // #2232 - sizeof...(Args)
|
||||
TEST_CASE(sizeof22); // #2599
|
||||
TEST_CASE(sizeof23); // #2604
|
||||
TEST_CASE(sizeofsizeof);
|
||||
TEST_CASE(casting);
|
||||
|
||||
|
@ -1416,23 +1414,6 @@ private:
|
|||
tok(code);
|
||||
}
|
||||
|
||||
void sizeof22() {
|
||||
// ticket #2599 segmentation fault
|
||||
const char code[] = "sizeof\n";
|
||||
|
||||
// don't segfault
|
||||
tok(code);
|
||||
}
|
||||
|
||||
void sizeof23() {
|
||||
// ticket #2604 segmentation fault
|
||||
const char code[] = "sizeof <= A\n";
|
||||
|
||||
// don't segfault
|
||||
tok(code);
|
||||
}
|
||||
|
||||
|
||||
void sizeofsizeof() {
|
||||
// ticket #1682
|
||||
const char code[] = "void f()\n"
|
||||
|
|
Loading…
Reference in New Issue