This commit is contained in:
Sebastien Debrard 2011-03-17 12:31:43 +01:00
commit b6adb91505
4 changed files with 120 additions and 7 deletions

View File

@ -1467,6 +1467,9 @@ void Scope::getVariableList()
continue;
tok = checkVariable(tok, varaccess);
if (!tok)
break;
}
}
@ -1515,7 +1518,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
bool isArray = false;
if (isVariableDeclaration(tok, vartok, typetok, isArray))
if (tok && isVariableDeclaration(tok, vartok, typetok, isArray))
{
isClass = (!typetok->isStandardType() && vartok->previous()->str() != "*");
tok = vartok->next();

View File

@ -1234,10 +1234,21 @@ void Tokenizer::simplifyTypedef()
}
// function: typedef ... ( .... type )( ... );
else if (tok->tokAt(offset)->str() == "(" &&
// typedef ... (( .... type )( ... ));
else if ((tok->tokAt(offset)->str() == "(" &&
Token::Match(tok->tokAt(offset)->link()->previous(), "%type% ) (") &&
Token::Match(tok->tokAt(offset)->link()->next()->link(), ") const|volatile|;"))
Token::Match(tok->tokAt(offset)->link()->next()->link(), ") const|volatile|;")) ||
(Token::simpleMatch(tok->tokAt(offset), "( (") &&
Token::Match(tok->tokAt(offset + 1)->link()->previous(), "%type% ) (") &&
Token::Match(tok->tokAt(offset + 1)->link()->next()->link(), ") const|volatile| )")))
{
if (tok->strAt(offset + 1) == "(")
offset++;
if (tok->tokAt(offset)->link()->strAt(-2) == "*")
functionPtr = true;
else
function = true;
funcStart = tok->tokAt(offset + 1);
funcEnd = tok->tokAt(offset)->link()->tokAt(-2);
typeName = tok->tokAt(offset)->link()->previous();
@ -1256,6 +1267,8 @@ void Tokenizer::simplifyTypedef()
}
tok = specEnd->next();
}
if (tok->str() == ")")
tok = tok->next();
}
else if (Token::Match(tok->tokAt(offset), "( %type% ("))
@ -1519,6 +1532,15 @@ void Tokenizer::simplifyTypedef()
if (simplifyType)
{
// can't simplify 'operator functionPtr ()' and 'functionPtr operator ... ()'
if (functionPtr && (tok2->previous()->str() == "operator" ||
tok2->next()->str() == "operator"))
{
simplifyType = false;
tok2 = tok2->next();
break;
}
// There are 2 categories of typedef substitutions:
// 1. variable declarations that preserve the variable name like
// global, local, and function parameters
@ -2955,6 +2977,25 @@ void Tokenizer::simplifyTemplatesInstantiate(const Token *tok,
if (tok2->str() != name)
continue;
// #2648 - simple fix for sizeof used as template parameter
// TODO: this is a bit hardcoded. make a bit more generic
if (Token::Match(tok2, "%var% < sizeof ( %type% ) >") && tok2->tokAt(4)->isStandardType())
{
// make sure standard types have a known size..
_typeSize["char"] = sizeof(char);
_typeSize["short"] = sizeof(short);
_typeSize["int"] = sizeof(int);
_typeSize["long"] = sizeof(long);
_typeSize["float"] = sizeof(float);
_typeSize["double"] = sizeof(double);
_typeSize["size_t"] = sizeof(size_t);
Token * const tok3 = tok2->next();
const unsigned int sz = sizeOfType(tok3->tokAt(3));
Token::eraseTokens(tok3, tok3->tokAt(5));
tok3->insertToken(MathLib::toString<unsigned int>(sz));
}
if (Token::Match(tok2->previous(), "[;{}=]") &&
!simplifyTemplatesInstantiateMatch(*iter2, name, type.size(), isfunc ? "(" : "*| %var%"))
continue;
@ -8517,8 +8558,14 @@ void Tokenizer::removeExceptionSpecifications(Token *tok) const
else if (tok->str() == "}")
break;
else if (Token::simpleMatch(tok, ") throw ("))
else if (Token::Match(tok, ") const| throw ("))
{
if (tok->next()->str() == "const")
{
Token::eraseTokens(tok->next(), tok->tokAt(3)->link());
tok = tok->next();
}
else
Token::eraseTokens(tok, tok->tokAt(2)->link());
tok->deleteNext();
}
@ -9463,7 +9510,7 @@ void Tokenizer::simplifyOperatorName()
par = par->next();
done = false;
}
if (Token::Match(par, "[<>+-*&/=.]") || Token::Match(par, "==|!=|<=|>="))
if (Token::Match(par, "[<>+-*&/=.!]") || Token::Match(par, "==|!=|<=|>="))
{
op += par->str();
par = par->next();

View File

@ -196,6 +196,7 @@ private:
TEST_CASE(symboldatabase13); // ticket #2577
TEST_CASE(symboldatabase14); // ticket #2589
TEST_CASE(symboldatabase15); // ticket #2591
TEST_CASE(symboldatabase16); // ticket #2637
}
// Check the operator Equal
@ -3300,6 +3301,11 @@ private:
" { return 0; }\n"
"};\n");
ASSERT_EQUALS("", errout.str());
checkConst("class Fred {\n"
" const std::string foo() const throw() { return ""; }\n"
"};\n");
ASSERT_EQUALS("", errout.str());
}
void const2()
@ -5791,6 +5797,14 @@ private:
ASSERT_EQUALS("", errout.str());
}
void symboldatabase16()
{
// ticket #2637 - segmentation fault
checkConst("{} const const\n");
ASSERT_EQUALS("", errout.str());
}
};
REGISTER_TEST(TestClass)

View File

@ -114,6 +114,7 @@ private:
TEST_CASE(template21);
TEST_CASE(template22);
TEST_CASE(template23);
TEST_CASE(template24); // #2648 - using sizeof in template parameter
TEST_CASE(template_unhandled);
TEST_CASE(template_default_parameter);
TEST_CASE(template_default_type);
@ -246,6 +247,8 @@ private:
TEST_CASE(simplifyTypedef82); // ticket #2403
TEST_CASE(simplifyTypedef83); // ticket #2620
TEST_CASE(simplifyTypedef84); // ticket #2630
TEST_CASE(simplifyTypedef85); // ticket #2651
TEST_CASE(simplifyTypedef86); // ticket #2581
TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -2038,6 +2041,24 @@ private:
ASSERT_EQUALS(expected, sizeof_(code));
}
void template24()
{
// #2648
const char code[] = "template<int n> struct B\n"
"{\n"
" int a[n];\n"
"};\n"
"\n"
"template<int x> class bitset: B<sizeof(int)>\n"
"{};\n"
"\n"
"bitset<1> z;";
const char expected[] = "; "
"bitset<1> z ; "
"class bitset<1> : B<4> { } "
"struct B<4> { int a [ 4 ] ; }";
ASSERT_EQUALS(expected, sizeof_(code));
}
void template_unhandled()
{
@ -4986,6 +5007,34 @@ private:
ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str());
}
void simplifyTypedef85() // ticket #2651
{
const char code[] = "typedef FOO ((BAR)(void, int, const int, int*));\n";
const char expected[] = ";";
checkSimplifyTypedef(code);
ASSERT_EQUALS(expected, sizeof_(code));
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedef86() // ticket #2581
{
const char code[] = "class relational {\n"
" typedef void (safe_bool_helper::*safe_bool)();\n"
"public:\n"
" operator safe_bool() const;\n"
" safe_bool operator!() const;\n"
"};\n";
const char expected[] = "class relational { "
"; "
"public: "
"operatorsafe_bool ( ) const ; "
"safe_bool operator! ( ) const ; "
"} ;";
checkSimplifyTypedef(code);
ASSERT_EQUALS(expected, sizeof_(code));
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedefFunction1()
{
{