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

This commit is contained in:
Robert Reif 2010-07-07 07:40:11 +02:00 committed by Daniel Marjamäki
parent dc2a0a6468
commit b0f1d5669b
2 changed files with 32 additions and 3 deletions

View File

@ -1188,12 +1188,13 @@ void Tokenizer::simplifyTypedef()
// 1. variable declarations that preserve the variable name like // 1. variable declarations that preserve the variable name like
// global, local, and function parameters // global, local, and function parameters
// 2. not variable declarations that have no name like derived // 2. not variable declarations that have no name like derived
// classes, casts, and template parameters // classes, casts, operators, and template parameters
// try to determine which catagory this substitution is // try to determine which catagory this substitution is
bool isDerived = false; bool isDerived = false;
bool inCast = false; bool inCast = false;
bool inTemplate = false; bool inTemplate = false;
bool inOperator = 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% {|,");
@ -1209,6 +1210,11 @@ void Tokenizer::simplifyTypedef()
Token::Match(tok2->next(), "&|*| &|*| >|,")) Token::Match(tok2->next(), "&|*| &|*| >|,"))
inTemplate = true; inTemplate = true;
// check for operator
if (Token::Match(tok2->previous(), "operator") ||
Token::Match(tok2->tokAt(-2), "operator const"))
inOperator = true;
// skip over class or struct in derived class declaration // skip over class or struct in derived class declaration
if (isDerived && Token::Match(typeStart, "class|struct")) if (isDerived && Token::Match(typeStart, "class|struct"))
typeStart = typeStart->next(); typeStart = typeStart->next();
@ -1305,7 +1311,7 @@ void Tokenizer::simplifyTypedef()
{ {
if (tok2->next()->str() == "(") if (tok2->next()->str() == "(")
tok2 = tok2->next()->link(); tok2 = tok2->next()->link();
else if (!Token::Match(tok2->next(), "[|>|;")) else if (!inOperator && !Token::Match(tok2->next(), "[|>|;"))
{ {
tok2 = tok2->next(); tok2 = tok2->next();
while (Token::Match(tok2, "*|&") && while (Token::Match(tok2, "*|&") &&
@ -7444,7 +7450,8 @@ void Tokenizer::simplifyConst()
for (Token *tok = _tokens; tok; tok = tok->next()) for (Token *tok = _tokens; tok; tok = tok->next())
{ {
if (Token::Match(tok, "[;{}(,] %type% const") && if (Token::Match(tok, "[;{}(,] %type% const") &&
tok->next()->str().find(":") == std::string::npos) tok->next()->str().find(":") == std::string::npos &&
tok->next()->str() != "operator")
{ {
tok->tokAt(2)->str(tok->tokAt(1)->str()); tok->tokAt(2)->str(tok->tokAt(1)->str());
tok->tokAt(1)->str("const"); tok->tokAt(1)->str("const");

View File

@ -206,6 +206,7 @@ private:
TEST_CASE(simplifyTypedef53); // ticket #1801 TEST_CASE(simplifyTypedef53); // ticket #1801
TEST_CASE(simplifyTypedef54); // ticket #1814 TEST_CASE(simplifyTypedef54); // ticket #1814
TEST_CASE(simplifyTypedef55); TEST_CASE(simplifyTypedef55);
TEST_CASE(simplifyTypedef56); // ticket #1829
TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685 TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -4246,6 +4247,27 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void simplifyTypedef56() // ticket #1829
{
const char code[] = "struct C {\n"
" typedef void (*fptr)();\n"
" const fptr pr;\n"
" operator const fptr& () { return pr; }\n"
"};\n";
// The expected result..
const std::string expected("struct C { "
"; "
"const void * pr ; " // this gets simplified to a regular pointer
"operator const void ( * ) ( ) & ( ) { return pr ; } "
"} ;");
ASSERT_EQUALS(expected, sizeof_(code));
// Check for output..
checkSimplifyTypedef(code);
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedefFunction1() void simplifyTypedefFunction1()
{ {
{ {