diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index bbcd1bd6b89..6063e313f2d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9482,8 +9482,15 @@ void Tokenizer::simplifyFunctionTryCatch() if (!Token::Match(tok, "try {|:")) continue; const Token* par = tok->previous(); - while (par && par->isKeyword()) + while (par && !Token::Match(par, "[);]")) { + if (par->str() == ">") { + if (const Token* ob = par->findOpeningBracket()) { + par = ob; + continue; + } + } par = par->previous(); + } if (!TokenList::isFunctionHead(par, "try")) // TODO: this is supposed to a list of characters and not strings continue; diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 26b24d649c8..ee10b8b4887 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -2379,7 +2379,7 @@ const Token * TokenList::isFunctionHead(const Token *tok, const std::string &suf tok = tok->linkAt(1)->next(); if (Token::Match(tok, "%name% (") && tok->isUpperCaseName()) tok = tok->linkAt(1)->next(); - if (tok && tok->originalName() == "->") { // trailing return type + if (tok && (tok->str() == "->" || tok->originalName() == "->")) { // trailing return type for (tok = tok->next(); tok && !Token::Match(tok, ";|{|override|final|}|)|]"); tok = tok->next()) if (tok->link() && Token::Match(tok, "<|[|(")) tok = tok->link(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index d5c770169e4..3cf00724cf8 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -2030,6 +2030,26 @@ class TestTokenizer : public TestFixture { "void S::func() const\n" "try { f(); }\n" "catch (...) { g(); }\n")); + + ASSERT_EQUALS("struct D : B {\n" // #15126 + "void f ( ) override { try { } catch ( ... ) { } }\n" + "void g ( ) final { try { } catch ( ... ) { } }\n" + "void i ( ) & override { try { } catch ( ... ) { } }\n" + "void j ( ) const && override { try { } catch ( ... ) { } }\n" + "auto k ( ) . std :: nullptr_t override { try { } catch ( ... ) { } }\n" + "auto l ( ) . W < decltype ( 1 ) > override { try { } catch ( ... ) { } }\n" + "} ;", + tokenizeAndStringify("struct D : B {\n" + " void f() override try {} catch (...) {}\n" + " void g() final try {} catch (...) {}\n" + " void i() & override try {} catch (...) {}\n" + " void j() const && override try {} catch (...) {}\n" + " auto k() -> std::nullptr_t override try {} catch (...) {}\n" + " auto l() -> W override try {} catch (...) {}\n" + "};\n")); + ASSERT_EQUALS("[test.cpp:6:5]: (debug) auto token with no type. [autoNoType]\n" + "[test.cpp:7:5]: (debug) auto token with no type. [autoNoType]\n", + errout_str()); } // Simplify "((..))" into "(..)"