Fixed #9728 (Support function level try blocks)
This commit is contained in:
parent
d553df75c6
commit
da27159d7c
|
@ -4802,6 +4802,8 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
|
||||||
|
|
||||||
reportUnknownMacros();
|
reportUnknownMacros();
|
||||||
|
|
||||||
|
simplifyFunctionTryCatch();
|
||||||
|
|
||||||
simplifyHeadersAndUnusedTemplates();
|
simplifyHeadersAndUnusedTemplates();
|
||||||
|
|
||||||
// Remove __asm..
|
// Remove __asm..
|
||||||
|
@ -10513,6 +10515,39 @@ void Tokenizer::simplifyWhile0()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tokenizer::simplifyFunctionTryCatch()
|
||||||
|
{
|
||||||
|
if (!isCPP())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (Token * tok = list.front(); tok; tok = tok->next()) {
|
||||||
|
if (!Token::simpleMatch(tok, "try {"))
|
||||||
|
continue;
|
||||||
|
if (!isFunctionHead(tok->previous(), "try"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// find the end of the last catch block
|
||||||
|
Token * const tryEndToken = tok->linkAt(1);
|
||||||
|
Token * endToken = tryEndToken;
|
||||||
|
while (Token::simpleMatch(endToken, "} catch (")) {
|
||||||
|
endToken = endToken->linkAt(2)->next();
|
||||||
|
if (!endToken)
|
||||||
|
break;
|
||||||
|
if (endToken->str() != "{") {
|
||||||
|
endToken = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
endToken = endToken->link();
|
||||||
|
}
|
||||||
|
if (!endToken || endToken == tryEndToken)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tok->previous()->insertToken("{");
|
||||||
|
endToken->insertToken("}");
|
||||||
|
Token::createMutualLinks(tok->previous(), endToken->next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Tokenizer::simplifyErrNoInWhile()
|
void Tokenizer::simplifyErrNoInWhile()
|
||||||
{
|
{
|
||||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||||
|
|
|
@ -511,6 +511,12 @@ public:
|
||||||
*/
|
*/
|
||||||
void simplifyFunctionParameters();
|
void simplifyFunctionParameters();
|
||||||
|
|
||||||
|
/** Simplify function level try blocks:
|
||||||
|
* Convert "void f() try {} catch (int) {}"
|
||||||
|
* to "void f() { try {} catch (int) {} }"
|
||||||
|
*/
|
||||||
|
void simplifyFunctionTryCatch();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplify templates
|
* Simplify templates
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -147,6 +147,8 @@ private:
|
||||||
TEST_CASE(simplifyFunctionParametersMultiTemplate);
|
TEST_CASE(simplifyFunctionParametersMultiTemplate);
|
||||||
TEST_CASE(simplifyFunctionParametersErrors);
|
TEST_CASE(simplifyFunctionParametersErrors);
|
||||||
|
|
||||||
|
TEST_CASE(simplifyFunctionTryCatch);
|
||||||
|
|
||||||
TEST_CASE(removeParentheses1); // Ticket #61
|
TEST_CASE(removeParentheses1); // Ticket #61
|
||||||
TEST_CASE(removeParentheses3);
|
TEST_CASE(removeParentheses3);
|
||||||
TEST_CASE(removeParentheses4); // Ticket #390
|
TEST_CASE(removeParentheses4); // Ticket #390
|
||||||
|
@ -1454,6 +1456,36 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void simplifyFunctionTryCatch() {
|
||||||
|
ASSERT_EQUALS("void foo ( ) { try {\n"
|
||||||
|
"} catch ( int ) {\n"
|
||||||
|
"} catch ( char ) {\n"
|
||||||
|
"} }",
|
||||||
|
tokenizeAndStringify("void foo() try {\n"
|
||||||
|
"} catch (int) {\n"
|
||||||
|
"} catch (char) {\n"
|
||||||
|
"}"));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("void foo ( ) { try {\n"
|
||||||
|
"struct S {\n"
|
||||||
|
"void bar ( ) { try {\n"
|
||||||
|
"} catch ( int ) {\n"
|
||||||
|
"} catch ( char ) {\n"
|
||||||
|
"} }\n"
|
||||||
|
"} ;\n"
|
||||||
|
"} catch ( long ) {\n"
|
||||||
|
"} }",
|
||||||
|
tokenizeAndStringify("void foo() try {\n"
|
||||||
|
" struct S {\n"
|
||||||
|
" void bar() try {\n"
|
||||||
|
" } catch (int) {\n"
|
||||||
|
" } catch (char) {\n"
|
||||||
|
" }\n"
|
||||||
|
" };\n"
|
||||||
|
"} catch (long) {\n"
|
||||||
|
"}"));
|
||||||
|
}
|
||||||
|
|
||||||
// Simplify "((..))" into "(..)"
|
// Simplify "((..))" into "(..)"
|
||||||
void removeParentheses1() {
|
void removeParentheses1() {
|
||||||
const char code[] = "void foo()"
|
const char code[] = "void foo()"
|
||||||
|
@ -6100,7 +6132,8 @@ private:
|
||||||
|
|
||||||
void findGarbageCode() { // Test Tokenizer::findGarbageCode()
|
void findGarbageCode() { // Test Tokenizer::findGarbageCode()
|
||||||
// C++ try/catch in global scope
|
// C++ try/catch in global scope
|
||||||
ASSERT_THROW_EQUALS(tokenizeAndStringify("void f() try { }"), InternalError, "syntax error: keyword 'try' is not allowed 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) { }"));
|
||||||
|
|
||||||
// before if|for|while|switch
|
// before if|for|while|switch
|
||||||
ASSERT_NO_THROW(tokenizeAndStringify("void f() { do switch (a) {} while (1); }"));
|
ASSERT_NO_THROW(tokenizeAndStringify("void f() { do switch (a) {} while (1); }"));
|
||||||
|
|
Loading…
Reference in New Issue