Fixed #1588 (typedef struct incorrectly simplified)
This commit is contained in:
parent
7f7e621ecb
commit
67fafd4028
|
@ -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--;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue