TemplateSimplifier: Fixed wrong match when inner template parameters are wrongly counted (#3818)
This commit is contained in:
parent
d68d035e22
commit
4ec12209dc
|
@ -1013,6 +1013,7 @@ bool TemplateSimplifier::simplifyTemplateInstantions(
|
||||||
std::vector<const Token *> typesUsedInTemplateInstantion;
|
std::vector<const Token *> typesUsedInTemplateInstantion;
|
||||||
std::string typeForNewNameStr;
|
std::string typeForNewNameStr;
|
||||||
std::string templateMatchPattern(name + " < ");
|
std::string templateMatchPattern(name + " < ");
|
||||||
|
unsigned int indentlevel = 0;
|
||||||
for (const Token *tok3 = tok2->tokAt(2); tok3 && tok3->str() != ">"; tok3 = tok3->next()) {
|
for (const Token *tok3 = tok2->tokAt(2); tok3 && tok3->str() != ">"; tok3 = tok3->next()) {
|
||||||
// #2648 - unhandled parenthesis => bail out
|
// #2648 - unhandled parenthesis => bail out
|
||||||
// #2721 - unhandled [ => bail out
|
// #2721 - unhandled [ => bail out
|
||||||
|
@ -1024,9 +1025,13 @@ bool TemplateSimplifier::simplifyTemplateInstantions(
|
||||||
typeForNewNameStr.clear();
|
typeForNewNameStr.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (tok3->str() == "<" && templateParameters(tok3) > 0)
|
||||||
|
++indentlevel;
|
||||||
|
else if (indentlevel > 0 && Token::simpleMatch(tok3, "> ,"))
|
||||||
|
--indentlevel;
|
||||||
templateMatchPattern += tok3->str();
|
templateMatchPattern += tok3->str();
|
||||||
templateMatchPattern += " ";
|
templateMatchPattern += " ";
|
||||||
if (Token::Match(tok3->previous(), "[<,]"))
|
if (indentlevel == 0 && Token::Match(tok3->previous(), "[<,]"))
|
||||||
typesUsedInTemplateInstantion.push_back(tok3);
|
typesUsedInTemplateInstantion.push_back(tok3);
|
||||||
// add additional type information
|
// add additional type information
|
||||||
if (tok3->isUnsigned())
|
if (tok3->isUnsigned())
|
||||||
|
|
|
@ -125,6 +125,7 @@ private:
|
||||||
TEST_CASE(template29); // #3449 - don't crash for garbage code
|
TEST_CASE(template29); // #3449 - don't crash for garbage code
|
||||||
TEST_CASE(template30); // #3529 - template < template < ..
|
TEST_CASE(template30); // #3529 - template < template < ..
|
||||||
TEST_CASE(template31); // #4010 - reference type
|
TEST_CASE(template31); // #4010 - reference type
|
||||||
|
TEST_CASE(template32); // #3818 - mismatching template not handled well
|
||||||
TEST_CASE(template_unhandled);
|
TEST_CASE(template_unhandled);
|
||||||
TEST_CASE(template_default_parameter);
|
TEST_CASE(template_default_parameter);
|
||||||
TEST_CASE(template_default_type);
|
TEST_CASE(template_default_type);
|
||||||
|
@ -2153,6 +2154,23 @@ private:
|
||||||
ASSERT_EQUALS("A<int&> a ; struct A<int&> { }", tok(code));
|
ASSERT_EQUALS("A<int&> a ; struct A<int&> { }", tok(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void template32() {
|
||||||
|
// #3818 - mismatching template not handled well
|
||||||
|
const char code[] = "template <class T1, class T2, class T3, class T4 > struct A { };\n"
|
||||||
|
"\n"
|
||||||
|
"template <class T>\n"
|
||||||
|
"struct B\n"
|
||||||
|
"{\n"
|
||||||
|
" public:\n"
|
||||||
|
" A < int, Pair<T, int>, int > a;\n" // mismatching parameters => don't instantiate
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"B<int> b;\n";
|
||||||
|
ASSERT_EQUALS("template < class T1 , class T2 , class T3 , class T4 > struct A { } ; "
|
||||||
|
"B<int> b ; "
|
||||||
|
"struct B<int> { public: A < int , Pair < int , int > , int > a ; }", tok(code));
|
||||||
|
}
|
||||||
|
|
||||||
void template_unhandled() {
|
void template_unhandled() {
|
||||||
// An unhandled template usage should be simplified..
|
// An unhandled template usage should be simplified..
|
||||||
ASSERT_EQUALS("x<int> ( ) ;", tok("x<int>();"));
|
ASSERT_EQUALS("x<int> ( ) ;", tok("x<int>();"));
|
||||||
|
|
Loading…
Reference in New Issue