From 389ab80b6393ae1d2cd02061c31da99f8bd19aca Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 14 Aug 2011 18:06:05 -0400 Subject: [PATCH] fix #2999 (false positive: (style) Struct 'Fred' hides typedef with same name) --- lib/tokenize.cpp | 35 ++++++++++++++++++++++++++--------- lib/tokenize.h | 2 +- test/testsimplifytokens.cpp | 14 ++++++++++++++ 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 8b070efe1..5ed99d914 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -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,14 +1077,25 @@ 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)) { - tok->deleteThis(); - tok->deleteThis(); - tok->deleteThis(); - tok->deleteThis(); - continue; + if (tok->strAt(1) == "enum") + { + tok->deleteThis(); + tok->deleteThis(); + tok->deleteThis(); + 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; @@ -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; diff --git a/lib/tokenize.h b/lib/tokenize.h index eb0155947..94a37c0c7 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -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); /** diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 21826bd48..58d3a9348 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -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() { {