Fixed #1588 (typedef struct incorrectly simplified)
This commit is contained in:
parent
3bbb2e1d7f
commit
d2bb4964d0
|
@ -544,9 +544,9 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// look backwards
|
// look backwards
|
||||||
if (Token::Match(tok->previous(), "typedef|}|>|struct") ||
|
if (Token::Match(tok->previous(), "typedef|}|>") ||
|
||||||
(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|public|private|protected") &&
|
||||||
!Token::Match(tok->tokAt(-2), "friend class"))))
|
!Token::Match(tok->tokAt(-2), "friend class"))))
|
||||||
{
|
{
|
||||||
// scan backwards for the end of the previous statement
|
// scan backwards for the end of the previous statement
|
||||||
|
@ -577,6 +577,34 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (tok->previous()->str() == "union")
|
||||||
|
{
|
||||||
|
if (tok->next()->str() != ";")
|
||||||
|
{
|
||||||
|
duplicateTypedefError(*tokPtr, name, "Union");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// forward declaration after declaration
|
||||||
|
duplicateDeclarationError(*tokPtr, name, "Union");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tok->previous()->str() == "class")
|
||||||
|
{
|
||||||
|
if (tok->next()->str() != ";")
|
||||||
|
{
|
||||||
|
duplicateTypedefError(*tokPtr, name, "Class");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// forward declaration after declaration
|
||||||
|
duplicateDeclarationError(*tokPtr, name, "Class");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (tok->previous()->str() == "{")
|
else if (tok->previous()->str() == "{")
|
||||||
level--;
|
level--;
|
||||||
|
|
||||||
|
@ -639,10 +667,10 @@ void Tokenizer::simplifyTypedef()
|
||||||
else if (tok->str() != "typedef")
|
else if (tok->str() != "typedef")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// pull struct, union or enum definition out of typedef
|
// pull struct, union, enum or class definition out of typedef
|
||||||
// use typedef name for unnamed struct, union or enum
|
// use typedef name for unnamed struct, union, enum or class
|
||||||
if (Token::Match(tok->next(), "struct|enum|union %type% {") ||
|
if (Token::Match(tok->next(), "struct|enum|union|class %type% {") ||
|
||||||
Token::Match(tok->next(), "struct|enum|union {"))
|
Token::Match(tok->next(), "struct|enum|union|class {"))
|
||||||
{
|
{
|
||||||
Token *tok1;
|
Token *tok1;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
@ -935,6 +963,9 @@ void Tokenizer::simplifyTypedef()
|
||||||
|
|
||||||
if (simplifyType)
|
if (simplifyType)
|
||||||
{
|
{
|
||||||
|
bool isDerived = false;
|
||||||
|
isDerived = Token::Match(tok2->previous(), "public|protected|private %type% {|,");
|
||||||
|
|
||||||
bool inCast = false;
|
bool inCast = false;
|
||||||
|
|
||||||
if ((tok2->previous()->str() == "(" && tok2->next()->str() == ")") ||
|
if ((tok2->previous()->str() == "(" && tok2->next()->str() == ")") ||
|
||||||
|
@ -942,6 +973,10 @@ void Tokenizer::simplifyTypedef()
|
||||||
Token::Match(tok2->next(), "> (")))
|
Token::Match(tok2->next(), "> (")))
|
||||||
inCast = true;
|
inCast = true;
|
||||||
|
|
||||||
|
// skip over class or struct in derived class declaration
|
||||||
|
if (isDerived && Token::Match(typeStart, "class|struct"))
|
||||||
|
typeStart = typeStart->next();
|
||||||
|
|
||||||
tok2->str(typeStart->str());
|
tok2->str(typeStart->str());
|
||||||
Token * nextToken;
|
Token * nextToken;
|
||||||
std::stack<Token *> links;
|
std::stack<Token *> links;
|
||||||
|
|
|
@ -182,6 +182,7 @@ private:
|
||||||
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(simplifyTypedef43); // ticket #1588
|
||||||
|
TEST_CASE(simplifyTypedef44);
|
||||||
|
|
||||||
TEST_CASE(reverseArraySyntax)
|
TEST_CASE(reverseArraySyntax)
|
||||||
TEST_CASE(simplify_numeric_condition)
|
TEST_CASE(simplify_numeric_condition)
|
||||||
|
@ -3714,27 +3715,163 @@ private:
|
||||||
checkSimplifyTypedef("typedef struct A { } A;\n"
|
checkSimplifyTypedef("typedef struct A { } A;\n"
|
||||||
"struct A;");
|
"struct A;");
|
||||||
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Struct 'A' forward declaration unnecessary, already declared\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Struct 'A' forward declaration unnecessary, already declared\n", errout.str());
|
||||||
|
|
||||||
|
checkSimplifyTypedef("typedef union A { int i; float f; } A;\n"
|
||||||
|
"union A;");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Union 'A' forward declaration unnecessary, already declared\n", errout.str());
|
||||||
|
|
||||||
|
checkSimplifyTypedef("typedef std::map<std::string, int> A;\n"
|
||||||
|
"class A;");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Class 'A' forward declaration unnecessary, already declared\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplifyTypedef43()
|
void simplifyTypedef43()
|
||||||
{
|
{
|
||||||
// ticket #1588
|
// ticket #1588
|
||||||
const char code[] = "typedef struct foo A;\n"
|
{
|
||||||
"struct A\n"
|
const char code[] = "typedef struct foo A;\n"
|
||||||
"{\n"
|
"struct A\n"
|
||||||
" int alloclen;\n"
|
"{\n"
|
||||||
"};\n";
|
" int alloclen;\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
// The expected result..
|
// The expected result..
|
||||||
const std::string expected("; "
|
const std::string expected("; "
|
||||||
"struct A "
|
"struct A "
|
||||||
"{ "
|
"{ "
|
||||||
"int alloclen ; "
|
"int alloclen ; "
|
||||||
"} ;");
|
"} ;");
|
||||||
ASSERT_EQUALS(expected, sizeof_(code));
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
|
||||||
checkSimplifyTypedef(code);
|
checkSimplifyTypedef(code);
|
||||||
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Struct 'A' hides typedef with same name\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Struct 'A' hides typedef with same name\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "typedef union foo A;\n"
|
||||||
|
"union A\n"
|
||||||
|
"{\n"
|
||||||
|
" int alloclen;\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
// The expected result..
|
||||||
|
const std::string expected("; "
|
||||||
|
"union A "
|
||||||
|
"{ "
|
||||||
|
"int alloclen ; "
|
||||||
|
"} ;");
|
||||||
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
|
||||||
|
checkSimplifyTypedef(code);
|
||||||
|
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Union 'A' hides typedef with same name\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "typedef class foo A;\n"
|
||||||
|
"class A\n"
|
||||||
|
"{\n"
|
||||||
|
" int alloclen;\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
// The expected result..
|
||||||
|
const std::string expected("; "
|
||||||
|
"class A "
|
||||||
|
"{ "
|
||||||
|
"int alloclen ; "
|
||||||
|
"} ;");
|
||||||
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
|
||||||
|
checkSimplifyTypedef(code);
|
||||||
|
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) Class 'A' hides typedef with same name\n", errout.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void simplifyTypedef44()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const char code[] = "typedef std::map<std::string, int> Map;\n"
|
||||||
|
"class MyMap : public Map\n"
|
||||||
|
"{\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
// The expected result..
|
||||||
|
const std::string expected("; "
|
||||||
|
"class MyMap : public std :: map < std :: string , int > "
|
||||||
|
"{ "
|
||||||
|
"} ;");
|
||||||
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
|
||||||
|
checkSimplifyTypedef(code);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "typedef std::map<std::string, int> Map;\n"
|
||||||
|
"class MyMap : protected Map\n"
|
||||||
|
"{\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
// The expected result..
|
||||||
|
const std::string expected("; "
|
||||||
|
"class MyMap : protected std :: map < std :: string , int > "
|
||||||
|
"{ "
|
||||||
|
"} ;");
|
||||||
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
|
||||||
|
checkSimplifyTypedef(code);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "typedef std::map<std::string, int> Map;\n"
|
||||||
|
"class MyMap : private Map\n"
|
||||||
|
"{\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
// The expected result..
|
||||||
|
const std::string expected("; "
|
||||||
|
"class MyMap : private std :: map < std :: string , int > "
|
||||||
|
"{ "
|
||||||
|
"} ;");
|
||||||
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
|
||||||
|
checkSimplifyTypedef(code);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "typedef struct foo { } A;\n"
|
||||||
|
"struct MyA : public A\n"
|
||||||
|
"{\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
// The expected result..
|
||||||
|
const std::string expected("struct foo { } ; ; "
|
||||||
|
"struct MyA : public foo "
|
||||||
|
"{ "
|
||||||
|
"} ;");
|
||||||
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
|
||||||
|
checkSimplifyTypedef(code);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "typedef class foo { } A;\n"
|
||||||
|
"class MyA : public A\n"
|
||||||
|
"{\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
|
// The expected result..
|
||||||
|
const std::string expected("class foo { } ; ; "
|
||||||
|
"class MyA : public foo "
|
||||||
|
"{ "
|
||||||
|
"} ;");
|
||||||
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
|
||||||
|
checkSimplifyTypedef(code);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reverseArraySyntax()
|
void reverseArraySyntax()
|
||||||
|
|
Loading…
Reference in New Issue