Fix 10438: FP knownConditionTrueFalse after return in a catch clause (#3429)
This commit is contained in:
parent
dccebb98ea
commit
b788e41191
|
@ -666,11 +666,23 @@ struct ForwardTraversal {
|
|||
}
|
||||
} else if (Token::simpleMatch(tok, "try {")) {
|
||||
Token* endBlock = tok->next()->link();
|
||||
Analyzer::Action a = analyzeScope(endBlock);
|
||||
if (updateRange(tok->next(), endBlock, depth - 1) == Progress::Break)
|
||||
return Break();
|
||||
if (a.isModified())
|
||||
ForwardTraversal tryTraversal = fork();
|
||||
tryTraversal.updateRange(tok->next(), endBlock, depth - 1);
|
||||
bool bail = tryTraversal.actions.isModified();
|
||||
if (bail)
|
||||
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;
|
||||
} else if (Token::simpleMatch(tok, "do {")) {
|
||||
Token* endBlock = tok->next()->link();
|
||||
|
|
|
@ -119,6 +119,7 @@ private:
|
|||
TEST_CASE(alwaysTrueInfer);
|
||||
TEST_CASE(alwaysTrueContainer);
|
||||
TEST_CASE(alwaysTrueLoop);
|
||||
TEST_CASE(alwaysTrueTryCatch);
|
||||
TEST_CASE(multiConditionAlwaysTrue);
|
||||
TEST_CASE(duplicateCondition);
|
||||
|
||||
|
@ -4079,6 +4080,44 @@ private:
|
|||
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() {
|
||||
check("void f() {\n"
|
||||
" int val = 0;\n"
|
||||
|
|
Loading…
Reference in New Issue