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);
|
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
|
// check if this statement is a duplicate definition
|
||||||
bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
|
bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
|
||||||
{
|
{
|
||||||
// check for an end of definition
|
// check for an end of definition
|
||||||
const Token * tok = *tokPtr;
|
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();
|
const Token * end = tok->next();
|
||||||
|
|
||||||
|
@ -514,7 +540,7 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// look backwards
|
// look backwards
|
||||||
if (Token::Match(tok->previous(), "typedef|}|>") ||
|
if (Token::Match(tok->previous(), "typedef|}|>|struct") ||
|
||||||
(Token::Match(tok->previous(), "%type%") &&
|
(Token::Match(tok->previous(), "%type%") &&
|
||||||
(!Token::Match(tok->previous(), "return|new|const|friend|struct") &&
|
(!Token::Match(tok->previous(), "return|new|const|friend|struct") &&
|
||||||
!Token::Match(tok->tokAt(-2), "friend class"))))
|
!Token::Match(tok->tokAt(-2), "friend class"))))
|
||||||
|
@ -533,6 +559,20 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
|
||||||
duplicateTypedefError(*tokPtr, name, "Enum");
|
duplicateTypedefError(*tokPtr, name, "Enum");
|
||||||
return true;
|
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() == "{")
|
else if (tok->previous()->str() == "{")
|
||||||
level--;
|
level--;
|
||||||
|
|
||||||
|
|
|
@ -449,7 +449,7 @@ public:
|
||||||
|
|
||||||
bool duplicateTypedef(Token **tokPtr, const Token *name);
|
bool duplicateTypedef(Token **tokPtr, const Token *name);
|
||||||
void duplicateTypedefError(const Token *tok1, const Token *tok2, const std::string & type);
|
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:
|
private:
|
||||||
/** Disable copy constructor, no implementation */
|
/** Disable copy constructor, no implementation */
|
||||||
|
|
|
@ -180,6 +180,7 @@ private:
|
||||||
TEST_CASE(simplifyTypedef40);
|
TEST_CASE(simplifyTypedef40);
|
||||||
TEST_CASE(simplifyTypedef41); // ticket #1488
|
TEST_CASE(simplifyTypedef41); // ticket #1488
|
||||||
TEST_CASE(simplifyTypedef42); // ticket #1506
|
TEST_CASE(simplifyTypedef42); // ticket #1506
|
||||||
|
TEST_CASE(simplifyTypedef43); // ticket #1588
|
||||||
|
|
||||||
TEST_CASE(reverseArraySyntax)
|
TEST_CASE(reverseArraySyntax)
|
||||||
TEST_CASE(simplify_numeric_condition)
|
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"
|
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: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: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()
|
void simplifyTypedef36()
|
||||||
|
@ -3663,7 +3664,28 @@ private:
|
||||||
// ticket #1506
|
// ticket #1506
|
||||||
checkSimplifyTypedef("typedef struct A { } A;\n"
|
checkSimplifyTypedef("typedef struct A { } A;\n"
|
||||||
"struct A;");
|
"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()
|
void reverseArraySyntax()
|
||||||
|
|
Loading…
Reference in New Issue