Fixed #1456 (PATCH: Variable hides typedef with same name false positive)

This commit is contained in:
Daniel Marjamäki 2010-02-27 07:27:51 +01:00
parent ce0131a1e6
commit a8ee4a03f0
2 changed files with 93 additions and 2 deletions

View File

@ -397,7 +397,7 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
{
// check for an end of definition
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();
@ -423,6 +423,39 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
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)
@ -461,7 +494,7 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name)
// look backwards
if (Token::Match(tok->previous(), "typedef|}|>") ||
(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
int level = (tok->previous()->str() == "}") ? 1 : 0;

View File

@ -176,6 +176,8 @@ private:
TEST_CASE(simplifyTypedef37); // ticket #1449
TEST_CASE(simplifyTypedef38);
TEST_CASE(simplifyTypedef39);
TEST_CASE(simplifyTypedef40);
TEST_CASE(reverseArraySyntax)
TEST_CASE(simplify_numeric_condition)
@ -3420,6 +3422,62 @@ private:
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()
{
ASSERT_EQUALS("a [ 13 ]", tok("13[a]"));