Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions lib/templatesimplifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,21 +429,21 @@ std::set<std::string> TemplateSimplifier::expandSpecialized(Token *tokens)
ostr << " ";
ostr << tok3->str();
}
if (!Token::simpleMatch(tok3, "> ("))
if (!Token::Match(tok3, "> (|{"))
continue;
s = ostr.str();
}

// save search pattern..
const std::string pattern(s + " > (");
const std::string pattern(s + " >");

// remove spaces to create new name
s.erase(std::remove(s.begin(), s.end(), ' '), s.end());
const std::string name(s + ">");
expandedtemplates.insert(name);

// Rename template..
Token::eraseTokens(tok2, Token::findsimplematch(tok2, "("));
Token::eraseTokens(tok2, Token::findsimplematch(tok2, "<")->findClosingBracket()->next());
tok2->str(name);

// delete the "template < >"
Expand All @@ -452,7 +452,7 @@ std::set<std::string> TemplateSimplifier::expandSpecialized(Token *tokens)

// Use this special template in the code..
while (nullptr != (tok2 = const_cast<Token *>(Token::findmatch(tok2, pattern.c_str())))) {
Token::eraseTokens(tok2, Token::findsimplematch(tok2, "("));
Token::eraseTokens(tok2, Token::findsimplematch(tok2, "<")->findClosingBracket()->next());
tok2->str(name);
}
}
Expand Down Expand Up @@ -700,7 +700,7 @@ int TemplateSimplifier::getTemplateNamePosition(const Token *tok)
{
// get the position of the template name
int namepos = 0, starAmpPossiblePosition = 0;
if (Token::Match(tok, "> class|struct %type% {|:"))
if (Token::Match(tok, "> class|struct %type% {|:|<"))
namepos = 2;
else if (Token::Match(tok, "> %type% *|&| %type% ("))
namepos = 2;
Expand Down
15 changes: 14 additions & 1 deletion test/testsimplifytemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class TestSimplifyTemplate : public TestFixture {
TEST_CASE(template50); // #4272 - simple partial specialization
TEST_CASE(template51); // #6172 - crash upon valid code
TEST_CASE(template52); // #6437 - crash upon valid code
TEST_CASE(template53); // #4335 - bail out for valid code
TEST_CASE(template_unhandled);
TEST_CASE(template_default_parameter);
TEST_CASE(template_default_type);
Expand All @@ -96,11 +97,12 @@ class TestSimplifyTemplate : public TestFixture {
TEST_CASE(templateNamePosition);
}

std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Unspecified) {
std::string tok(const char code[], bool simplify = true, bool debugwarnings = false, Settings::PlatformType type = Settings::Unspecified) {
errout.str("");

Settings settings;
settings.addEnabled("portability");
settings.debugwarnings = debugwarnings;
settings.platform(type);
Tokenizer tokenizer(&settings, this);

Expand Down Expand Up @@ -938,6 +940,17 @@ class TestSimplifyTemplate : public TestFixture {
"int value = calculate_value<1,1>();");
}

void template53() { // #4335
tok("template<int N> struct Factorial { "
" enum { value = N * Factorial<N - 1>::value }; "
"};"
"template <> struct Factorial<0> { "
" enum { value = 1 }; "
"};"
"const int x = Factorial<4>::value;", /*simplify=*/true, /*debugwarnings=*/true);
ASSERT_EQUALS("", errout.str());
}

void template_default_parameter() {
{
const char code[] = "template <class T, int n=3>\n"
Expand Down