Fixed #1588 (typedef struct incorrectly simplified)

This commit is contained in:
Robert Reif 2010-04-12 19:05:31 +02:00 committed by Daniel Marjamäki
parent 7f7e621ecb
commit 67fafd4028
3 changed files with 67 additions and 5 deletions

View File

@ -414,12 +414,38 @@ void Tokenizer::duplicateTypedefError(const Token *tok1, const Token *tok2, cons
Check::reportError(errmsg);
}
void Tokenizer::duplicateDeclarationError(const Token *tok1, const Token *tok2, const std::string &type)
{
if (!(_settings && _settings->_checkCodingStyle))
return;
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
ErrorLogger::ErrorMessage::FileLocation loc;
loc.line = tok1->linenr();
loc.file = file(tok1);
locationList.push_back(loc);
loc.line = tok2->linenr();
loc.file = file(tok2);
locationList.push_back(loc);
const ErrorLogger::ErrorMessage errmsg(locationList,
"style",
std::string(type + " '" + tok2->str() +
"' forward declaration unnecessary, already declared"),
"unnecessaryForwardDeclaration");
if (_errorLogger)
_errorLogger->reportErr(errmsg);
else
Check::reportError(errmsg);
}
// check if this statement is a duplicate definition
bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
{
// check for an end of definition
const Token * tok = *tokPtr;
if (tok && tok->next() && Token::Match(tok->next(), ";|,|[|=|)|>|("))
if (tok && tok->next() && Token::Match(tok->next(), ";|,|[|=|)|>|(|{"))
{
const Token * end = tok->next();
@ -514,7 +540,7 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
else
{
// look backwards
if (Token::Match(tok->previous(), "typedef|}|>") ||
if (Token::Match(tok->previous(), "typedef|}|>|struct") ||
(Token::Match(tok->previous(), "%type%") &&
(!Token::Match(tok->previous(), "return|new|const|friend|struct") &&
!Token::Match(tok->tokAt(-2), "friend class"))))
@ -533,6 +559,20 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
duplicateTypedefError(*tokPtr, name, "Enum");
return true;
}
else if (tok->previous()->str() == "struct")
{
if (tok->next()->str() != ";")
{
duplicateTypedefError(*tokPtr, name, "Struct");
return true;
}
else
{
// forward declaration after declaration
duplicateDeclarationError(*tokPtr, name, "Struct");
return false;
}
}
else if (tok->previous()->str() == "{")
level--;

View File

@ -449,7 +449,7 @@ public:
bool duplicateTypedef(Token **tokPtr, const Token *name);
void duplicateTypedefError(const Token *tok1, const Token *tok2, const std::string & type);
void duplicateDeclarationError(const Token *tok1, const Token *tok2, const std::string &type);
private:
/** Disable copy constructor, no implementation */

View File

@ -180,6 +180,7 @@ private:
TEST_CASE(simplifyTypedef40);
TEST_CASE(simplifyTypedef41); // ticket #1488
TEST_CASE(simplifyTypedef42); // ticket #1506
TEST_CASE(simplifyTypedef43); // ticket #1588
TEST_CASE(reverseArraySyntax)
TEST_CASE(simplify_numeric_condition)
@ -3519,7 +3520,7 @@ private:
ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:1]: (style) Typedef 'A' hides typedef with same name\n"
"[test.cpp:20] -> [test.cpp:1]: (style) Function parameter 'A' hides typedef with same name\n"
"[test.cpp:21] -> [test.cpp:1]: (style) Variable 'A' hides typedef with same name\n"
"[test.cpp:24] -> [test.cpp:1]: (style) Typedef 'A' hides typedef with same name\n", errout.str());
"[test.cpp:24] -> [test.cpp:1]: (style) Struct 'A' hides typedef with same name\n", errout.str());
}
void simplifyTypedef36()
@ -3663,7 +3664,28 @@ private:
// ticket #1506
checkSimplifyTypedef("typedef struct A { } A;\n"
"struct A;");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Struct 'A' forward declaration unnecessary, already declared\n", errout.str());
}
void simplifyTypedef43()
{
// ticket #1588
const char code[] = "typedef struct foo A;\n"
"struct A\n"
"{\n"
" int alloclen;\n"
"};\n";
// The expected result..
const std::string expected("; "
"struct A "
"{ "
"int alloclen ; "
"} ;");
ASSERT_EQUALS(expected, sizeof_(code));
checkSimplifyTypedef(code);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Struct 'A' hides typedef with same name\n", errout.str());
}
void reverseArraySyntax()