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
|
||||
{
|
||||
// look backwards
|
||||
if (Token::Match(tok->previous(), "typedef|}|>|struct") ||
|
||||
if (Token::Match(tok->previous(), "typedef|}|>") ||
|
||||
(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"))))
|
||||
{
|
||||
// scan backwards for the end of the previous statement
|
||||
|
@ -577,6 +577,34 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
|
|||
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() == "{")
|
||||
level--;
|
||||
|
||||
|
@ -639,10 +667,10 @@ void Tokenizer::simplifyTypedef()
|
|||
else if (tok->str() != "typedef")
|
||||
continue;
|
||||
|
||||
// pull struct, union or enum definition out of typedef
|
||||
// use typedef name for unnamed struct, union or enum
|
||||
if (Token::Match(tok->next(), "struct|enum|union %type% {") ||
|
||||
Token::Match(tok->next(), "struct|enum|union {"))
|
||||
// pull struct, union, enum or class definition out of typedef
|
||||
// use typedef name for unnamed struct, union, enum or class
|
||||
if (Token::Match(tok->next(), "struct|enum|union|class %type% {") ||
|
||||
Token::Match(tok->next(), "struct|enum|union|class {"))
|
||||
{
|
||||
Token *tok1;
|
||||
std::string name;
|
||||
|
@ -935,6 +963,9 @@ void Tokenizer::simplifyTypedef()
|
|||
|
||||
if (simplifyType)
|
||||
{
|
||||
bool isDerived = false;
|
||||
isDerived = Token::Match(tok2->previous(), "public|protected|private %type% {|,");
|
||||
|
||||
bool inCast = false;
|
||||
|
||||
if ((tok2->previous()->str() == "(" && tok2->next()->str() == ")") ||
|
||||
|
@ -942,6 +973,10 @@ void Tokenizer::simplifyTypedef()
|
|||
Token::Match(tok2->next(), "> (")))
|
||||
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());
|
||||
Token * nextToken;
|
||||
std::stack<Token *> links;
|
||||
|
|
|
@ -182,6 +182,7 @@ private:
|
|||
TEST_CASE(simplifyTypedef41); // ticket #1488
|
||||
TEST_CASE(simplifyTypedef42); // ticket #1506
|
||||
TEST_CASE(simplifyTypedef43); // ticket #1588
|
||||
TEST_CASE(simplifyTypedef44);
|
||||
|
||||
TEST_CASE(reverseArraySyntax)
|
||||
TEST_CASE(simplify_numeric_condition)
|
||||
|
@ -3714,11 +3715,20 @@ private:
|
|||
checkSimplifyTypedef("typedef struct A { } A;\n"
|
||||
"struct A;");
|
||||
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()
|
||||
{
|
||||
// ticket #1588
|
||||
{
|
||||
const char code[] = "typedef struct foo A;\n"
|
||||
"struct A\n"
|
||||
"{\n"
|
||||
|
@ -3737,6 +3747,133 @@ private:
|
|||
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()
|
||||
{
|
||||
ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));
|
||||
|
|
Loading…
Reference in New Issue