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

View File

@ -637,7 +637,7 @@ public:
*/ */
void duplicateEnumError(const Token *tok1, const Token *tok2, const std::string & type); 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); 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(simplifyTypedef96); // ticket #2886
TEST_CASE(simplifyTypedef97); // ticket #2983 (segmentation fault) TEST_CASE(simplifyTypedef97); // ticket #2983 (segmentation fault)
TEST_CASE(simplifyTypedef98); // ticket #2963 TEST_CASE(simplifyTypedef98); // ticket #2963
TEST_CASE(simplifyTypedef99); // ticket #2999
TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685 TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -5357,6 +5358,19 @@ private:
ASSERT_EQUALS("", errout.str()); 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() void simplifyTypedefFunction1()
{ {
{ {