Fixed #1456 (PATCH: Variable hides typedef with same name false positive)
This commit is contained in:
parent
ce0131a1e6
commit
a8ee4a03f0
|
@ -397,7 +397,7 @@ 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();
|
||||||
|
|
||||||
|
@ -423,6 +423,39 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
|
||||||
|
|
||||||
end = end->next();
|
end = end->next();
|
||||||
}
|
}
|
||||||
|
end = end->next();
|
||||||
|
}
|
||||||
|
else if (end->str() == "(")
|
||||||
|
{
|
||||||
|
if (tok->previous()->str() == "operator")
|
||||||
|
{
|
||||||
|
// conversion operator
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (tok->previous()->str() == "typedef")
|
||||||
|
{
|
||||||
|
// typedef of function returning this type
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (Token::Match(tok->previous(), "public:|private:|protected:"))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (tok->previous()->str() == ">")
|
||||||
|
{
|
||||||
|
duplicateTypedefError(*tokPtr, name, "Template instantiation");
|
||||||
|
*tokPtr = end->link();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (Token::Match(tok->previous(), "%type%"))
|
||||||
|
{
|
||||||
|
if (end->link()->next()->str() == "{")
|
||||||
|
{
|
||||||
|
duplicateTypedefError(*tokPtr, name, "Function");
|
||||||
|
*tokPtr = end->link()->next()->link();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end)
|
if (end)
|
||||||
|
@ -461,7 +494,7 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
|
||||||
// look backwards
|
// look backwards
|
||||||
if (Token::Match(tok->previous(), "typedef|}|>") ||
|
if (Token::Match(tok->previous(), "typedef|}|>") ||
|
||||||
(Token::Match(tok->previous(), "%type%") &&
|
(Token::Match(tok->previous(), "%type%") &&
|
||||||
!Token::Match(tok->previous(), "return|new|const")))
|
!Token::Match(tok->previous(), "return|new|const|friend")))
|
||||||
{
|
{
|
||||||
// scan backwards for the end of the previous statement
|
// scan backwards for the end of the previous statement
|
||||||
int level = (tok->previous()->str() == "}") ? 1 : 0;
|
int level = (tok->previous()->str() == "}") ? 1 : 0;
|
||||||
|
|
|
@ -176,6 +176,8 @@ private:
|
||||||
TEST_CASE(simplifyTypedef37); // ticket #1449
|
TEST_CASE(simplifyTypedef37); // ticket #1449
|
||||||
TEST_CASE(simplifyTypedef38);
|
TEST_CASE(simplifyTypedef38);
|
||||||
TEST_CASE(simplifyTypedef39);
|
TEST_CASE(simplifyTypedef39);
|
||||||
|
TEST_CASE(simplifyTypedef40);
|
||||||
|
|
||||||
TEST_CASE(reverseArraySyntax)
|
TEST_CASE(reverseArraySyntax)
|
||||||
TEST_CASE(simplify_numeric_condition)
|
TEST_CASE(simplify_numeric_condition)
|
||||||
|
|
||||||
|
@ -3420,6 +3422,62 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void simplifyTypedef40()
|
||||||
|
{
|
||||||
|
const char code[] = "typedef int A;\n"
|
||||||
|
"typedef int B;\n"
|
||||||
|
"template <class A, class B> class C { };";
|
||||||
|
const char expected[] = "; ; ; ;";
|
||||||
|
ASSERT_EQUALS(expected, tok(code, false));
|
||||||
|
|
||||||
|
checkSimplifyTypedef(code);
|
||||||
|
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:1]: (style) Template parameter 'A' hides typedef with same name\n"
|
||||||
|
"[test.cpp:3] -> [test.cpp:2]: (style) Template parameter 'B' hides typedef with same name\n", errout.str());
|
||||||
|
|
||||||
|
checkSimplifyTypedef("typedef tuple<double&, const double&, const double, double*, const double*> t2;\n"
|
||||||
|
"void ordering_test()\n"
|
||||||
|
"{\n"
|
||||||
|
" tuple<short, float> t2(5, 3.3f);\n"
|
||||||
|
" BOOST_CHECK(t3 > t2);\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1]: (style) Template instantiation 't2' hides typedef with same name\n", errout.str());
|
||||||
|
|
||||||
|
checkSimplifyTypedef("class MyOverflowingUnsigned\n"
|
||||||
|
"{\n"
|
||||||
|
"public:\n"
|
||||||
|
" typedef unsigned self_type::* bool_type;\n"
|
||||||
|
" operator bool_type() const { return this->v_ ? &self_type::v_ : 0; }\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
checkSimplifyTypedef("typedef int (*fptr_type)(int, int);\n"
|
||||||
|
"struct which_one {\n"
|
||||||
|
" typedef fptr_type (*result_type)(bool x);\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
checkSimplifyTypedef("class my_configuration\n"
|
||||||
|
"{\n"
|
||||||
|
"public:\n"
|
||||||
|
" template < typename T >\n"
|
||||||
|
" class hook\n"
|
||||||
|
" {\n"
|
||||||
|
" public:\n"
|
||||||
|
" typedef ::boost::rational<T> rational_type;\n"
|
||||||
|
" public:\n"
|
||||||
|
" rational_type ( &r_ )[ 9 ];\n"
|
||||||
|
" };\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
checkSimplifyTypedef("class A\n"
|
||||||
|
"{\n"
|
||||||
|
" typedef B b;\n"
|
||||||
|
" friend b;\n"
|
||||||
|
"};");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void reverseArraySyntax()
|
void reverseArraySyntax()
|
||||||
{
|
{
|
||||||
ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));
|
ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));
|
||||||
|
|
Loading…
Reference in New Issue