Fixed #4446 (Crash on complex C++ template)
This commit is contained in:
parent
2c1f579b3b
commit
8cca41774d
|
@ -499,7 +499,7 @@ std::list<Token *> TemplateSimplifier::getTemplateInstantiations(Token *tokens)
|
||||||
|
|
||||||
|
|
||||||
void TemplateSimplifier::useDefaultArgumentValues(const std::list<Token *> &templates,
|
void TemplateSimplifier::useDefaultArgumentValues(const std::list<Token *> &templates,
|
||||||
const std::list<Token *> &templateInstantiations)
|
std::list<Token *> * const templateInstantiations)
|
||||||
{
|
{
|
||||||
for (std::list<Token *>::const_iterator iter1 = templates.begin(); iter1 != templates.end(); ++iter1) {
|
for (std::list<Token *>::const_iterator iter1 = templates.begin(); iter1 != templates.end(); ++iter1) {
|
||||||
// template parameters with default value has syntax such as:
|
// template parameters with default value has syntax such as:
|
||||||
|
@ -534,7 +534,7 @@ void TemplateSimplifier::useDefaultArgumentValues(const std::list<Token *> &temp
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// iterate through all template instantiations
|
// iterate through all template instantiations
|
||||||
for (std::list<Token *>::const_iterator iter2 = templateInstantiations.begin(); iter2 != templateInstantiations.end(); ++iter2) {
|
for (std::list<Token *>::const_iterator iter2 = templateInstantiations->begin(); iter2 != templateInstantiations->end(); ++iter2) {
|
||||||
Token *tok = *iter2;
|
Token *tok = *iter2;
|
||||||
|
|
||||||
if (!Token::Match(tok, (classname + " < %any%").c_str()))
|
if (!Token::Match(tok, (classname + " < %any%").c_str()))
|
||||||
|
@ -580,11 +580,27 @@ void TemplateSimplifier::useDefaultArgumentValues(const std::list<Token *> &temp
|
||||||
|
|
||||||
for (std::list<Token *>::iterator it = eq.begin(); it != eq.end(); ++it) {
|
for (std::list<Token *>::iterator it = eq.begin(); it != eq.end(); ++it) {
|
||||||
Token * const eqtok = *it;
|
Token * const eqtok = *it;
|
||||||
const Token *tok2;
|
Token *tok2;
|
||||||
|
int indentlevel = 0;
|
||||||
for (tok2 = eqtok->next(); tok2; tok2 = tok2->next()) {
|
for (tok2 = eqtok->next(); tok2; tok2 = tok2->next()) {
|
||||||
if (tok2->str() == "(")
|
if (tok2->str() == "(")
|
||||||
tok2 = tok2->link();
|
tok2 = tok2->link();
|
||||||
else if (tok2->str() == "," || tok2->str() == ">")
|
else if (Token::Match(tok2, "%type% <") && templateParameters(tok2->next())) {
|
||||||
|
std::list<Token*>::iterator ti = std::find(templateInstantiations->begin(),
|
||||||
|
templateInstantiations->end(),
|
||||||
|
tok2);
|
||||||
|
if (ti != templateInstantiations->end())
|
||||||
|
templateInstantiations->erase(ti);
|
||||||
|
++indentlevel;
|
||||||
|
} else if (indentlevel > 0 && tok2->str() == ">")
|
||||||
|
--indentlevel;
|
||||||
|
else if (indentlevel > 0 && tok2->str() == ">>") {
|
||||||
|
indentlevel -= 2;
|
||||||
|
if (indentlevel < 0)
|
||||||
|
tok2->str(">");
|
||||||
|
} else if (indentlevel == 0 && Token::Match(tok2, ",|>|>>"))
|
||||||
|
break;
|
||||||
|
if (indentlevel < 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Token::eraseTokens(eqtok, tok2);
|
Token::eraseTokens(eqtok, tok2);
|
||||||
|
@ -1263,7 +1279,7 @@ void TemplateSimplifier::simplifyTemplates(
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Template arguments with default values
|
// Template arguments with default values
|
||||||
TemplateSimplifier::useDefaultArgumentValues(templates, templateInstantiations);
|
TemplateSimplifier::useDefaultArgumentValues(templates, &templateInstantiations);
|
||||||
|
|
||||||
// expand templates
|
// expand templates
|
||||||
//bool done = false;
|
//bool done = false;
|
||||||
|
|
|
@ -88,7 +88,7 @@ public:
|
||||||
* @param templateInstantiations list of template instantiations
|
* @param templateInstantiations list of template instantiations
|
||||||
*/
|
*/
|
||||||
static void useDefaultArgumentValues(const std::list<Token *> &templates,
|
static void useDefaultArgumentValues(const std::list<Token *> &templates,
|
||||||
const std::list<Token *> &templateInstantiations);
|
std::list<Token *> *templateInstantiations);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Match template declaration/instantiation
|
* Match template declaration/instantiation
|
||||||
|
|
|
@ -2429,6 +2429,14 @@ private:
|
||||||
);
|
);
|
||||||
TODO_ASSERT_EQUALS(wanted, current, tok(code));
|
TODO_ASSERT_EQUALS(wanted, current, tok(code));
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
const char code[] = "template<class T, class T2 = A<T>> class B {};\n"
|
||||||
|
"template<class B = A, typename C = C<B>> class C;\n"
|
||||||
|
"template<class B, typename C> class D { };\n";
|
||||||
|
ASSERT_EQUALS("template < class T , class T2 > class B { } ; "
|
||||||
|
"template < class B , typename C > class C ; "
|
||||||
|
"template < class B , typename C > class D { } ;", tok(code));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void template_default_type() {
|
void template_default_type() {
|
||||||
|
|
Loading…
Reference in New Issue