fix #2999 (false positive: (style) Struct 'Fred' hides typedef with same name)

This commit is contained in:
Robert Reif 2011-08-14 18:06:05 -04:00
parent d336e91049
commit 389ab80b63
3 changed files with 41 additions and 10 deletions

View File

@ -576,7 +576,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, const Token *typeDef)
bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name, const Token *typeDef, bool undefinedStruct)
{
// check for an end of definition
const Token * tok = *tokPtr;
@ -715,6 +715,12 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name, const Token
// declaration after forward declaration
return true;
}
else if (tok->next()->str() == "{")
{
if (!undefinedStruct)
duplicateTypedefError(*tokPtr, name, "Struct");
return true;
}
else if (tok->next()->str() != ";")
{
duplicateTypedefError(*tokPtr, name, "Struct");
@ -1071,8 +1077,11 @@ void Tokenizer::simplifyTypedef()
}
}
/** @todo add support for struct and union */
if (Token::Match(tok, "typedef enum %type% %type% ;") && tok->strAt(2) == tok->strAt(3))
/** @todo add support for union */
bool undefinedStruct = false;
if (Token::Match(tok, "typedef enum|struct %type% %type% ;") && tok->strAt(2) == tok->strAt(3))
{
if (tok->strAt(1) == "enum")
{
tok->deleteThis();
tok->deleteThis();
@ -1080,6 +1089,14 @@ void Tokenizer::simplifyTypedef()
tok->deleteThis();
continue;
}
else
{
const std::string pattern("struct " + tok->strAt(2) + " {|:");
const Token *tok2 = Token::findmatch(_tokens, pattern.c_str(), tok);
if (!tok2)
undefinedStruct = true;
}
}
Token *typeName;
std::list<std::string> pointers;
@ -1620,7 +1637,7 @@ void Tokenizer::simplifyTypedef()
{
tok2 = tok2->next();
}
else if (duplicateTypedef(&tok2, typeName, typeDef))
else if (duplicateTypedef(&tok2, typeName, typeDef, undefinedStruct))
{
exitScope = scope;

View File

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

View File

@ -264,6 +264,7 @@ private:
TEST_CASE(simplifyTypedef96); // ticket #2886
TEST_CASE(simplifyTypedef97); // ticket #2983 (segmentation fault)
TEST_CASE(simplifyTypedef98); // ticket #2963
TEST_CASE(simplifyTypedef99); // ticket #2999
TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -5357,6 +5358,19 @@ private:
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedef99() // ticket #2999
{
const char code[] = "typedef struct Fred Fred;\n"
"struct Fred { };\n";
sizeof_(code);
ASSERT_EQUALS("", errout.str());
const char code1[] = "struct Fred { };\n"
"typedef struct Fred Fred;\n";
sizeof_(code1);
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedefFunction1()
{
{