Tokenizer::simplifyTemplates: First simple fix for problems when using sizeof in template parameter

This commit is contained in:
Daniel Marjamäki 2011-03-16 22:16:30 +01:00
parent f7cbc90c84
commit fec9edf628
2 changed files with 38 additions and 0 deletions

View File

@ -2977,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;

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);
@ -2040,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()
{