Fixed #8969 (syntax error: template) (#1647)

Fixed template detection to handle multi-token template parameters.
This commit is contained in:
IOBYTE 2019-02-07 02:50:49 -05:00 committed by amai2012
parent aa730f45c6
commit 7025254c26
2 changed files with 24 additions and 2 deletions

View File

@ -1860,8 +1860,14 @@ void Tokenizer::combineOperators()
// combine +-*/ and = // combine +-*/ and =
if (c2 == '=' && (std::strchr("+-*/%|^=!<>", c1))) { if (c2 == '=' && (std::strchr("+-*/%|^=!<>", c1))) {
if (cpp && Token::Match(tok->tokAt(-2), "< %any% >")) // skip templates
continue; if (cpp && tok->str() == ">") {
const Token *opening = tok->findOpeningBracket();
if (opening) {
if (Token::Match(opening->previous(), "%name%"))
continue;
}
}
tok->str(tok->str() + c2); tok->str(tok->str() + c2);
tok->deleteNext(); tok->deleteNext();
continue; continue;

View File

@ -137,6 +137,7 @@ private:
TEST_CASE(template97); TEST_CASE(template97);
TEST_CASE(template98); // #8959 TEST_CASE(template98); // #8959
TEST_CASE(template99); // #8960 TEST_CASE(template99); // #8960
TEST_CASE(template100); // #8967
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)
@ -2101,6 +2102,21 @@ private:
ASSERT_EQUALS(exp, tok(code)); ASSERT_EQUALS(exp, tok(code));
} }
void template100() { // #8967
const char code[] = "enum class Device { I2C0, I2C1 };\n"
"template <Device D>\n"
"const char* deviceFile;\n"
"template <>\n"
"const char* deviceFile<Device::I2C0> = \"/tmp/i2c-0\";\n";
const char exp[] = "enum class Device { I2C0 , I2C1 } ; "
"template < Device D > "
"const char * deviceFile ; "
"const char * deviceFile<Device::I2C0> ; deviceFile<Device::I2C0> = \"/tmp/i2c-0\" ;";
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"