Fixed #1316 (### Internal error in Cppcheck. Please report it.)

This commit is contained in:
Robert Reif 2010-01-27 19:03:24 +01:00 committed by Daniel Marjamäki
parent 32fcb8fe18
commit 45b6b9e5a1
2 changed files with 63 additions and 12 deletions

View File

@ -446,6 +446,7 @@ void Tokenizer::simplifyTypedef()
const char *type1 = 0;
const char *type2 = 0;
const char *type3 = 0;
const char *type4 = 0;
const char *typeName = 0;
std::list<std::string> pointers;
Token *start = 0;
@ -454,6 +455,7 @@ void Tokenizer::simplifyTypedef()
Token *typeDef = tok;
int offset = 1;
bool functionPtr = false;
bool functionRef = false;
if (Token::Match(tok->next(), "%type% <") ||
Token::Match(tok->next(), "%type% %type% <") ||
@ -510,9 +512,21 @@ void Tokenizer::simplifyTypedef()
{
type2 = tok->strAt(offset++);
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "%type%") &&
tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,"))
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "::"))
{
type3 = tok->strAt(offset++);
if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "%type%") &&
tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,"))
{
type4 = tok->strAt(offset++);
}
}
else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "%type%") &&
tok->tokAt(offset + 1) && !Token::Match(tok->tokAt(offset + 1), "[|;|,"))
{
type3 = tok->strAt(offset++);
}
}
}
else
@ -542,18 +556,22 @@ void Tokenizer::simplifyTypedef()
continue;
}
}
else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( * %type% ) ("))
else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( *|& %type% ) ("))
{
if (tok->tokAt(offset + 4)->link()->next())
{
functionPtr = true;
functionPtr = tok->tokAt(offset + 1)->str() == "*";
functionRef = tok->tokAt(offset + 1)->str() == "&";
typeName = tok->strAt(offset + 2);
start = tok->tokAt(offset + 4);
end = tok->tokAt(offset + 4)->link();
tok = end->next();
}
else
{
// internal error
continue;
}
}
else
{
@ -623,11 +641,11 @@ void Tokenizer::simplifyTypedef()
bool inCast = false;
if ((tok2->previous()->str() == "(" && tok2->next()->str() == ")") ||
(Token::Match(tok2->tokAt(-2), "static_cast <") &&
(Token::Match(tok2->tokAt(-1), "<") &&
Token::Match(tok2->next(), "> (")))
inCast = true;
if (start && end && !functionPtr)
if (start && end && !(functionPtr || functionRef))
{
tok2->str(start->str());
Token * nextToken;
@ -664,6 +682,11 @@ void Tokenizer::simplifyTypedef()
tok2->insertToken(type3);
tok2 = tok2->next();
}
if (type4)
{
tok2->insertToken(type4);
tok2 = tok2->next();
}
}
while (!pointers.empty())
@ -673,12 +696,15 @@ void Tokenizer::simplifyTypedef()
tok2 = tok2->next();
}
if (functionPtr)
if (functionPtr || functionRef)
{
tok2->insertToken("(");
tok2 = tok2->next();
Token *tok3 = tok2;
tok2->insertToken("*");
if (functionPtr)
tok2->insertToken("*");
else
tok2->insertToken("&");
tok2 = tok2->next();
if (!inCast)
@ -689,15 +715,20 @@ void Tokenizer::simplifyTypedef()
tok2 = tok2->tokAt(5)->link();
else
{
tok2 = tok2->next();
// skip over typedef parameter
if (tok2->next()->str() == "(")
{
tok2 = tok2->next()->link();
else
{
tok2 = tok2->next();
// skip over typedef parameter
if (tok2->next()->str() == "(")
{
tok2 = tok2->next()->link();
if (tok2->next()->str() == "(")
tok2 = tok2->next()->link();
}
}
}
}

View File

@ -163,6 +163,7 @@ private:
TEST_CASE(simplifyTypedef24);
TEST_CASE(simplifyTypedef25);
TEST_CASE(simplifyTypedef26);
TEST_CASE(simplifyTypedef27);
TEST_CASE(reverseArraySyntax)
TEST_CASE(simplify_numeric_condition)
@ -2920,6 +2921,25 @@ private:
}
}
void simplifyTypedef27()
{
// ticket #1316
const char code[] = "int main()\n"
"{\n"
" typedef int (*func_ptr)(float, double);\n"
" VERIFY((is_same<result_of<func_ptr(char, float)>::type, int>::value));\n"
"}";
const char expected[] =
"int main ( ) "
"{ "
"; "
"VERIFY ( ( is_same < result_of < int ( * ( char , float ) ) ( float , double ) > :: type , int > :: value ) ) ; "
"}";
ASSERT_EQUALS(expected, tok(code, false));
}
void reverseArraySyntax()
{
ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));