Skip to content

Commit 3e17c24

Browse files
IOBYTEdanmar
authored andcommitted
fix syntax error on template operator (danmar#2225)
1 parent 67971db commit 3e17c24

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

lib/token.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,14 @@ Token* Token::nextTemplateArgument() const
851851
return nullptr;
852852
}
853853

854+
static bool isOperator(const Token *tok)
855+
{
856+
if (tok->link())
857+
tok = tok->link();
858+
// TODO handle multi token operators
859+
return tok->strAt(-1) == "operator";
860+
}
861+
854862
const Token * Token::findClosingBracket() const
855863
{
856864
if (mStr != "<")
@@ -869,7 +877,8 @@ const Token * Token::findClosingBracket() const
869877
} else if (Token::Match(closing, "}|]|)|;"))
870878
return nullptr;
871879
// we can make some guesses for template parameters
872-
else if (closing->str() == "<" && closing->previous() && closing->previous()->isName() &&
880+
else if (closing->str() == "<" && closing->previous() &&
881+
(closing->previous()->isName() || isOperator(closing->previous())) &&
873882
(templateParameter ? templateParameters.find(closing->strAt(-1)) == templateParameters.end() : true))
874883
++depth;
875884
else if (closing->str() == ">") {

lib/tokenize.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6644,11 +6644,12 @@ void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, co
66446644
while (tok2 && tok2->str() != "," && tok2->str() != ";") {
66456645
if (Token::Match(tok2, "{|(|["))
66466646
tok2 = tok2->link();
6647+
const Token *tok3 = tok2;
66476648
if (!isC() && tok2->str() == "<" && TemplateSimplifier::templateParameters(tok2) > 0) {
66486649
tok2 = tok2->findClosingBracket();
66496650
}
66506651
if (!tok2)
6651-
syntaxError(nullptr); // #6881 invalid code
6652+
syntaxError(tok3); // #6881 invalid code
66526653
tok2 = tok2->next();
66536654
}
66546655
if (tok2 && tok2->str() == ";")

test/testsimplifytemplate.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ class TestSimplifyTemplate : public TestFixture {
187187
TEST_CASE(template147); // syntax error
188188
TEST_CASE(template148); // syntax error
189189
TEST_CASE(template149); // unknown macro
190+
TEST_CASE(template150); // syntax error
190191
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
191192
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
192193
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
@@ -3551,6 +3552,25 @@ class TestSimplifyTemplate : public TestFixture {
35513552
ASSERT_THROW_EQUALS(tok(code), InternalError, "There is an unknown macro here somewhere. Configuration is required. If BEGIN_VERSIONED_NAMESPACE_DECL is a macro then please configure it.");
35523553
}
35533554

3555+
void template150() { // syntax error
3556+
const char code[] = "struct Test {\n"
3557+
" template <typename T>\n"
3558+
" T &operator[] (T) {}\n"
3559+
"};\n"
3560+
"void foo() {\n"
3561+
" Test test;\n"
3562+
" const string type = test.operator[]<string>(\"type\");\n"
3563+
"}";
3564+
const char exp[] = "struct Test { "
3565+
"string & operator[]<string> ( string ) ; "
3566+
"} ; "
3567+
"void foo ( ) { "
3568+
"Test test ; "
3569+
"const string type = test . operator[]<string> ( \"type\" ) ; "
3570+
"} string & Test :: operator[]<string> ( string ) { }";
3571+
ASSERT_EQUALS(exp, tok(code));
3572+
}
3573+
35543574
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
35553575
const char code[] = "template <typename T> struct C {};\n"
35563576
"template <typename T> struct S {a};\n"

0 commit comments

Comments
 (0)