fix #2568 (False positive: (style) Union 'A_t' hides typedef with same name (forward declaration))

This commit is contained in:
Robert Reif 2011-02-11 19:09:24 -05:00
parent f5ed52b84b
commit 78b5361ec8
3 changed files with 28 additions and 6 deletions

View File

@ -509,7 +509,7 @@ void Tokenizer::duplicateDeclarationError(const Token *tok1, const Token *tok2,
}
// check if this statement is a duplicate definition
bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name, const Token *typeDef)
{
// check for an end of definition
const Token * tok = *tokPtr;
@ -624,7 +624,11 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
int level = (tok->previous()->str() == "}") ? 1 : 0;
while (tok && tok->previous() && (!Token::Match(tok->previous(), ";|{") || (level != 0)))
{
if (tok->previous()->str() == "typedef")
if (tok->previous()->str() == "}")
{
tok = tok->previous()->link();
}
else if (tok->previous()->str() == "typedef")
{
duplicateTypedefError(*tokPtr, name, "Typedef");
return true;
@ -636,7 +640,14 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
}
else if (tok->previous()->str() == "struct")
{
if (tok->next()->str() != ";")
if (tok->strAt(-2) == "typedef" &&
tok->next()->str() == "{" &&
typeDef->strAt(3) != "{")
{
// declaration after forward declaration
return true;
}
else if (tok->next()->str() != ";")
{
duplicateTypedefError(*tokPtr, name, "Struct");
return true;
@ -1373,7 +1384,7 @@ void Tokenizer::simplifyTypedef()
{
tok2 = tok2->next();
}
else if (duplicateTypedef(&tok2, typeName))
else if (duplicateTypedef(&tok2, typeName, typeDef))
{
exitScope = scope;

View File

@ -580,7 +580,7 @@ public:
*/
void duplicateEnumError(const Token *tok1, const Token *tok2, const std::string & type);
bool duplicateTypedef(Token **tokPtr, const Token *name);
bool duplicateTypedef(Token **tokPtr, const Token *name, const Token *typeDef);
void duplicateTypedefError(const Token *tok1, const Token *tok2, const std::string & type);
/**

View File

@ -235,6 +235,7 @@ private:
TEST_CASE(simplifyTypedef75); // ticket #2426
TEST_CASE(simplifyTypedef76); // ticket #2453
TEST_CASE(simplifyTypedef77); // ticket #2554
TEST_CASE(simplifyTypedef78); // ticket #2568
TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -3941,7 +3942,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) Struct 'A' hides typedef with same name\n", errout.str());
"[test.cpp:24] -> [test.cpp:1]: (style) Typedef 'A' hides typedef with same name\n", errout.str());
}
void simplifyTypedef36()
@ -4846,6 +4847,16 @@ private:
ASSERT_EQUALS(expected, sizeof_(code));
}
void simplifyTypedef78() // ticket #2568
{
const char code[] = "typedef struct A A_t;\n"
"A_t a;\n"
"typedef struct A { } A_t;\n"
"A_t a1;\n";
const std::string expected = "; struct A a ; struct A { } ; struct A a1 ;";
ASSERT_EQUALS(expected, sizeof_(code));
}
void simplifyTypedefFunction1()
{
{