Fixed #8880 (Regression: syntax error for valid C++ template code) (#1509)

This commit is contained in:
IOBYTE 2018-12-06 15:47:48 -05:00 committed by amai2012
parent a4dd423a18
commit a90c56ad76
2 changed files with 21 additions and 2 deletions

View File

@ -1047,8 +1047,14 @@ void TemplateSimplifier::expandTemplate(
start = templateDeclarationToken->next(); start = templateDeclarationToken->next();
end = templateDeclarationNameToken->linkAt(1)->next(); end = templateDeclarationNameToken->linkAt(1)->next();
} }
while (!Token::Match(end, ";|{|:")) unsigned int typeindentlevel = 0;
while (!(typeindentlevel == 0 && Token::Match(end, ";|{|:"))) {
if (Token::Match(end, "<|(|{"))
++typeindentlevel;
else if (Token::Match(end, ">|)|}"))
--typeindentlevel;
end = end->next(); end = end->next();
}
std::map<const Token *, Token *> links; std::map<const Token *, Token *> links;
while (start && start != end) { while (start && start != end) {
@ -1057,7 +1063,7 @@ void TemplateSimplifier::expandTemplate(
++itype; ++itype;
if (itype < typeParametersInDeclaration.size()) { if (itype < typeParametersInDeclaration.size()) {
unsigned int typeindentlevel = 0; typeindentlevel = 0;
for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype]; for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype];
typetok && (typeindentlevel > 0 || !Token::Match(typetok, ",|>")); typetok && (typeindentlevel > 0 || !Token::Match(typetok, ",|>"));
typetok = typetok->next()) { typetok = typetok->next()) {

View File

@ -121,6 +121,7 @@ private:
TEST_CASE(template81); TEST_CASE(template81);
TEST_CASE(template82); // 8603 TEST_CASE(template82); // 8603
TEST_CASE(template83); TEST_CASE(template83);
TEST_CASE(template84); // #8880
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..}; TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..}; TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template) TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
@ -1608,6 +1609,18 @@ private:
ASSERT_EQUALS(exp, tok(code)); ASSERT_EQUALS(exp, tok(code));
} }
void template84() { // #8880
const char code[] = "template <class b, int c, class>\n"
"auto d() -> typename a<decltype(b{})>::e {\n"
" d<int, c, int>();\n"
"}";
const char exp[] = "auto d<int,c,int> ( ) . a < decltype ( int { } ) > :: e ; "
"auto d<int,c,int> ( ) . a < decltype ( int { } ) > :: e { "
"d<int,c,int> ( ) ; "
"}";
ASSERT_EQUALS(exp, tok(code));
}
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..}; void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
const char code[] = "template <typename T> struct C {};\n" const char code[] = "template <typename T> struct C {};\n"
"template <typename T> struct S {a};\n" "template <typename T> struct S {a};\n"