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

View File

@ -163,6 +163,7 @@ private:
TEST_CASE(simplifyTypedef24); TEST_CASE(simplifyTypedef24);
TEST_CASE(simplifyTypedef25); TEST_CASE(simplifyTypedef25);
TEST_CASE(simplifyTypedef26); TEST_CASE(simplifyTypedef26);
TEST_CASE(simplifyTypedef27);
TEST_CASE(reverseArraySyntax) TEST_CASE(reverseArraySyntax)
TEST_CASE(simplify_numeric_condition) 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() void reverseArraySyntax()
{ {
ASSERT_EQUALS("a [ 13 ]", tok("13[a]")); ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));