Merge pull request #551 from simartin/ticket_4335
Ticket #4335: Properly detect and handle template class specialisations
This commit is contained in:
commit
a200e5b32f
|
@ -429,13 +429,13 @@ 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());
|
||||
|
@ -443,7 +443,7 @@ std::set<std::string> TemplateSimplifier::expandSpecialized(Token *tokens)
|
|||
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 < >"
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -694,7 +694,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;
|
||||
|
|
|
@ -83,6 +83,7 @@ private:
|
|||
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);
|
||||
|
@ -96,11 +97,12 @@ private:
|
|||
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);
|
||||
|
||||
|
@ -938,6 +940,17 @@ private:
|
|||
"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"
|
||||
|
|
Loading…
Reference in New Issue