fix syntax error on template operator (#2225)
This commit is contained in:
parent
67971db58f
commit
3e17c24dd8
|
@ -851,6 +851,14 @@ Token* Token::nextTemplateArgument() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static bool isOperator(const Token *tok)
|
||||
{
|
||||
if (tok->link())
|
||||
tok = tok->link();
|
||||
// TODO handle multi token operators
|
||||
return tok->strAt(-1) == "operator";
|
||||
}
|
||||
|
||||
const Token * Token::findClosingBracket() const
|
||||
{
|
||||
if (mStr != "<")
|
||||
|
@ -869,7 +877,8 @@ const Token * Token::findClosingBracket() const
|
|||
} else if (Token::Match(closing, "}|]|)|;"))
|
||||
return nullptr;
|
||||
// we can make some guesses for template parameters
|
||||
else if (closing->str() == "<" && closing->previous() && closing->previous()->isName() &&
|
||||
else if (closing->str() == "<" && closing->previous() &&
|
||||
(closing->previous()->isName() || isOperator(closing->previous())) &&
|
||||
(templateParameter ? templateParameters.find(closing->strAt(-1)) == templateParameters.end() : true))
|
||||
++depth;
|
||||
else if (closing->str() == ">") {
|
||||
|
|
|
@ -6644,11 +6644,12 @@ void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, co
|
|||
while (tok2 && tok2->str() != "," && tok2->str() != ";") {
|
||||
if (Token::Match(tok2, "{|(|["))
|
||||
tok2 = tok2->link();
|
||||
const Token *tok3 = tok2;
|
||||
if (!isC() && tok2->str() == "<" && TemplateSimplifier::templateParameters(tok2) > 0) {
|
||||
tok2 = tok2->findClosingBracket();
|
||||
}
|
||||
if (!tok2)
|
||||
syntaxError(nullptr); // #6881 invalid code
|
||||
syntaxError(tok3); // #6881 invalid code
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
if (tok2 && tok2->str() == ";")
|
||||
|
|
|
@ -187,6 +187,7 @@ private:
|
|||
TEST_CASE(template147); // syntax error
|
||||
TEST_CASE(template148); // syntax error
|
||||
TEST_CASE(template149); // unknown macro
|
||||
TEST_CASE(template150); // syntax error
|
||||
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_enum); // #6299 Syntax error in complex enum declaration (including template)
|
||||
|
@ -3551,6 +3552,25 @@ private:
|
|||
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.");
|
||||
}
|
||||
|
||||
void template150() { // syntax error
|
||||
const char code[] = "struct Test {\n"
|
||||
" template <typename T>\n"
|
||||
" T &operator[] (T) {}\n"
|
||||
"};\n"
|
||||
"void foo() {\n"
|
||||
" Test test;\n"
|
||||
" const string type = test.operator[]<string>(\"type\");\n"
|
||||
"}";
|
||||
const char exp[] = "struct Test { "
|
||||
"string & operator[]<string> ( string ) ; "
|
||||
"} ; "
|
||||
"void foo ( ) { "
|
||||
"Test test ; "
|
||||
"const string type = test . operator[]<string> ( \"type\" ) ; "
|
||||
"} string & Test :: operator[]<string> ( string ) { }";
|
||||
ASSERT_EQUALS(exp, tok(code));
|
||||
}
|
||||
|
||||
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
||||
const char code[] = "template <typename T> struct C {};\n"
|
||||
"template <typename T> struct S {a};\n"
|
||||
|
|
Loading…
Reference in New Issue