Fix #9716 Syntax error for function-try-block in global scope (#4305)

* Fix #9716 Syntax error for function-try-block in global scope

* static through instance

* Handle multiple catch blocks

* Add test

* Fix skip logic

* Handle init lists in simplifyFunctionTryCatch()
This commit is contained in:
chrchr-github 2022-07-31 14:49:50 +02:00 committed by GitHub
parent c878285a42
commit 38fdbe0890
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 2 deletions

View File

@ -7856,13 +7856,20 @@ void Tokenizer::simplifyFunctionTryCatch()
return;
for (Token * tok = list.front(); tok; tok = tok->next()) {
if (!Token::simpleMatch(tok, "try {"))
if (!Token::Match(tok, "try {|:"))
continue;
if (!isFunctionHead(tok->previous(), "try"))
continue;
Token* tryStartToken = tok->next();
while (Token::Match(tryStartToken, "[:,] %name% (|{")) // skip init list
tryStartToken = tryStartToken->linkAt(2)->next();
if (!Token::simpleMatch(tryStartToken, "{"))
syntaxError(tryStartToken, "Invalid function-try-catch block code. Did not find '{' for try body.");
// find the end of the last catch block
Token * const tryEndToken = tok->linkAt(1);
Token * const tryEndToken = tryStartToken->link();
Token * endToken = tryEndToken;
while (Token::simpleMatch(endToken, "} catch (")) {
endToken = endToken->linkAt(2)->next();

View File

@ -6560,6 +6560,18 @@ private:
// C++ try/catch in global scope
ASSERT_THROW_EQUALS(tokenizeAndStringify("try { }"), InternalError, "syntax error: keyword 'try' is not allowed in global scope");
ASSERT_NO_THROW(tokenizeAndStringify("void f() try { } catch (int) { }"));
ASSERT_NO_THROW(tokenizeAndStringify("struct S {\n" // #9716
" S();\n"
" int x, y;\n"
"};\n"
"S::S()\n"
" try : x(1), y{ 2 } { f(); }\n"
" catch (const std::exception& e) { g(); }\n"
" catch (...) { g(); }\n"));
ASSERT_NO_THROW(tokenizeAndStringify("void f()\n"
" try { g(); }\n"
" catch (const std::exception& e) { h(); }\n"
" catch (...) { h(); }\n"));
// before if|for|while|switch
ASSERT_NO_THROW(tokenizeAndStringify("void f() { do switch (a) {} while (1); }"));