Fixed #2554 (simplifyTypedef: wrong simplification for sizeof(array))

This commit is contained in:
Robert Reif 2011-02-08 19:47:14 -05:00
parent 9dd1515f6f
commit 7502cea4d3
2 changed files with 22 additions and 2 deletions

View File

@ -1382,13 +1382,14 @@ void Tokenizer::simplifyTypedef()
bool inCast = false; bool inCast = false;
bool inTemplate = false; bool inTemplate = false;
bool inOperator = false; bool inOperator = false;
bool inSizeof = false;
// check for derived class: class A : some_typedef { // check for derived class: class A : some_typedef {
isDerived = Token::Match(tok2->previous(), "public|protected|private %type% {|,"); isDerived = Token::Match(tok2->previous(), "public|protected|private %type% {|,");
// check for cast: (some_typedef) A or static_cast<some_typedef>(A) // check for cast: (some_typedef) A or static_cast<some_typedef>(A)
// todo: check for more complicated casts like: (const some_typedef *)A // todo: check for more complicated casts like: (const some_typedef *)A
if ((tok2->previous()->str() == "(" && tok2->next()->str() == ")") || if ((tok2->previous()->str() == "(" && tok2->next()->str() == ")" && tok2->strAt(-2) != "sizeof") ||
(tok2->previous()->str() == "<" && Token::simpleMatch(tok2->next(), "> ("))) (tok2->previous()->str() == "<" && Token::simpleMatch(tok2->next(), "> (")))
inCast = true; inCast = true;
@ -1397,6 +1398,9 @@ void Tokenizer::simplifyTypedef()
Token::Match(tok2->next(), "&|*| &|*| >|,")) Token::Match(tok2->next(), "&|*| &|*| >|,"))
inTemplate = true; inTemplate = true;
else if (Token::Match(tok2->tokAt(-2), "sizeof ( %type% )"))
inSizeof = true;
// check for operator // check for operator
if (Token::simpleMatch(tok2->previous(), "operator") || if (Token::simpleMatch(tok2->previous(), "operator") ||
Token::simpleMatch(tok2->tokAt(-2), "operator const")) Token::simpleMatch(tok2->tokAt(-2), "operator const"))
@ -1891,7 +1895,8 @@ void Tokenizer::simplifyTypedef()
{ {
do do
{ {
tok2 = tok2->next(); if (!inCast && !inSizeof)
tok2 = tok2->next();
Token * nextArrTok; Token * nextArrTok;
std::stack<Token *> arrLinks; std::stack<Token *> arrLinks;
for (nextArrTok = arrayStart; nextArrTok != arrayEnd->next(); nextArrTok = nextArrTok->next()) for (nextArrTok = arrayStart; nextArrTok != arrayEnd->next(); nextArrTok = nextArrTok->next())
@ -4059,6 +4064,13 @@ void Tokenizer::simplifySizeof()
sz = sizeOfType(decltok->tokAt(-2)); sz = sizeOfType(decltok->tokAt(-2));
} }
} }
else if (tok->strAt(3) == "[" && tok->tokAt(2)->isStandardType())
{
sz = sizeOfType(tok->tokAt(2));
if (sz == 0)
continue;
sz = sz * static_cast<unsigned long>(MathLib::toLongNumber(tok->strAt(4)));
}
if (sz > 0) if (sz > 0)
{ {

View File

@ -234,6 +234,7 @@ private:
TEST_CASE(simplifyTypedef74); // ticket #2414 TEST_CASE(simplifyTypedef74); // ticket #2414
TEST_CASE(simplifyTypedef75); // ticket #2426 TEST_CASE(simplifyTypedef75); // ticket #2426
TEST_CASE(simplifyTypedef76); // ticket #2453 TEST_CASE(simplifyTypedef76); // ticket #2453
TEST_CASE(simplifyTypedef77); // ticket #2554
TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685 TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -4838,6 +4839,13 @@ private:
ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str());
} }
void simplifyTypedef77() // ticket #2554
{
const char code[] = "typedef char Str[10]; int x = sizeof(Str);\n";
const std::string expected = "; int x ; x = 10 ;";
ASSERT_EQUALS(expected, sizeof_(code));
}
void simplifyTypedefFunction1() void simplifyTypedefFunction1()
{ {
{ {