Fix 10438: FP knownConditionTrueFalse after return in a catch clause (#3429)

This commit is contained in:
Paul Fultz II 2021-09-03 16:07:08 -05:00 committed by GitHub
parent dccebb98ea
commit b788e41191
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 4 deletions

View File

@ -666,11 +666,23 @@ struct ForwardTraversal {
} }
} else if (Token::simpleMatch(tok, "try {")) { } else if (Token::simpleMatch(tok, "try {")) {
Token* endBlock = tok->next()->link(); Token* endBlock = tok->next()->link();
Analyzer::Action a = analyzeScope(endBlock); ForwardTraversal tryTraversal = fork();
if (updateRange(tok->next(), endBlock, depth - 1) == Progress::Break) tryTraversal.updateRange(tok->next(), endBlock, depth - 1);
return Break(); bool bail = tryTraversal.actions.isModified();
if (a.isModified()) if (bail)
analyzer->lowerToPossible(); analyzer->lowerToPossible();
while (Token::simpleMatch(endBlock, "} catch (")) {
Token* endCatch = endBlock->linkAt(2);
if (!Token::simpleMatch(endCatch, ") {"))
return Break();
endBlock = endCatch->linkAt(1);
ForwardTraversal ft = fork();
ft.updateRange(endBlock->link(), endBlock, depth - 1);
bail |= ft.terminate != Analyzer::Terminate::None || ft.actions.isModified();
}
if (bail)
return Break();
tok = endBlock; tok = endBlock;
} else if (Token::simpleMatch(tok, "do {")) { } else if (Token::simpleMatch(tok, "do {")) {
Token* endBlock = tok->next()->link(); Token* endBlock = tok->next()->link();

View File

@ -119,6 +119,7 @@ private:
TEST_CASE(alwaysTrueInfer); TEST_CASE(alwaysTrueInfer);
TEST_CASE(alwaysTrueContainer); TEST_CASE(alwaysTrueContainer);
TEST_CASE(alwaysTrueLoop); TEST_CASE(alwaysTrueLoop);
TEST_CASE(alwaysTrueTryCatch);
TEST_CASE(multiConditionAlwaysTrue); TEST_CASE(multiConditionAlwaysTrue);
TEST_CASE(duplicateCondition); TEST_CASE(duplicateCondition);
@ -4079,6 +4080,44 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void alwaysTrueTryCatch()
{
check("void g();\n"
"void f(int x)\n"
"{\n"
" if( x ) {\n"
" try {\n"
" g();\n"
" }\n"
" catch(...) {\n"
" return;\n"
" }\n"
" }\n"
" g();\n"
" if( x ) {\n"
" g();\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void g();\n"
"void h();\n"
"void f(int x) {\n"
" if( x ) {\n"
" try {\n"
" g();\n"
" return;\n"
" }\n"
" catch( ... ) {}\n"
" }\n"
" h();\n"
" if( x ) {\n"
" g();\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void multiConditionAlwaysTrue() { void multiConditionAlwaysTrue() {
check("void f() {\n" check("void f() {\n"
" int val = 0;\n" " int val = 0;\n"