Fix issue 9686: Regression: ValueFlow should handle try/catch better (#2618)
This commit is contained in:
parent
ef30e53332
commit
2a09465a07
|
@ -287,6 +287,9 @@ struct ForwardTraversal {
|
||||||
analyzer->assume(condTok, !inElse, tok);
|
analyzer->assume(condTok, !inElse, tok);
|
||||||
if (Token::simpleMatch(tok, "} else {"))
|
if (Token::simpleMatch(tok, "} else {"))
|
||||||
tok = tok->linkAt(2);
|
tok = tok->linkAt(2);
|
||||||
|
} else if (Token::simpleMatch(tok, "}") && Token::simpleMatch(tok->link()->previous(), "try {")) {
|
||||||
|
if (!analyzer->lowerToPossible())
|
||||||
|
return Progress::Break;
|
||||||
} else if (Token::Match(tok, "if|while|for (") && Token::simpleMatch(tok->next()->link(), ") {")) {
|
} else if (Token::Match(tok, "if|while|for (") && Token::simpleMatch(tok->next()->link(), ") {")) {
|
||||||
Token* endCond = tok->next()->link();
|
Token* endCond = tok->next()->link();
|
||||||
Token* endBlock = endCond->next()->link();
|
Token* endBlock = endCond->next()->link();
|
||||||
|
@ -371,6 +374,14 @@ struct ForwardTraversal {
|
||||||
}
|
}
|
||||||
} else if (Token::simpleMatch(tok, "} else {")) {
|
} else if (Token::simpleMatch(tok, "} else {")) {
|
||||||
tok = tok->linkAt(2);
|
tok = tok->linkAt(2);
|
||||||
|
} else if (Token::simpleMatch(tok, "try {")) {
|
||||||
|
Token* endBlock = tok->next()->link();
|
||||||
|
ForwardAnalyzer::Action a = analyzeScope(endBlock);
|
||||||
|
if (updateRange(tok->next(), endBlock) == Progress::Break)
|
||||||
|
return Progress::Break;
|
||||||
|
if (a.isModified())
|
||||||
|
analyzer->lowerToPossible();
|
||||||
|
tok = endBlock;
|
||||||
} else if (Token::simpleMatch(tok, "do {")) {
|
} else if (Token::simpleMatch(tok, "do {")) {
|
||||||
Token* endBlock = tok->next()->link();
|
Token* endBlock = tok->next()->link();
|
||||||
if (updateLoop(endBlock, nullptr) == Progress::Break)
|
if (updateLoop(endBlock, nullptr) == Progress::Break)
|
||||||
|
|
|
@ -91,6 +91,7 @@ private:
|
||||||
TEST_CASE(valueFlowForwardFunction);
|
TEST_CASE(valueFlowForwardFunction);
|
||||||
TEST_CASE(valueFlowForwardTernary);
|
TEST_CASE(valueFlowForwardTernary);
|
||||||
TEST_CASE(valueFlowForwardLambda);
|
TEST_CASE(valueFlowForwardLambda);
|
||||||
|
TEST_CASE(valueFlowForwardTryCatch);
|
||||||
|
|
||||||
TEST_CASE(valueFlowFwdAnalysis);
|
TEST_CASE(valueFlowFwdAnalysis);
|
||||||
|
|
||||||
|
@ -2623,6 +2624,40 @@ private:
|
||||||
TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 3U, 3));
|
TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 3U, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void valueFlowForwardTryCatch() {
|
||||||
|
const char *code;
|
||||||
|
|
||||||
|
code = "void g1();\n"
|
||||||
|
"void g2();\n"
|
||||||
|
"void f()\n {"
|
||||||
|
" bool x = false;\n"
|
||||||
|
" try {\n"
|
||||||
|
" g1();\n"
|
||||||
|
" x = true;\n"
|
||||||
|
" g2();\n"
|
||||||
|
" }\n"
|
||||||
|
" catch (...) {\n"
|
||||||
|
" if (x) {}\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n";
|
||||||
|
ASSERT_EQUALS(true, testValueOfX(code, 11U, 1));
|
||||||
|
ASSERT_EQUALS(false, testValueOfXKnown(code, 11U, 1));
|
||||||
|
|
||||||
|
code = "void g1();\n"
|
||||||
|
"void g2();\n"
|
||||||
|
"void f()\n {"
|
||||||
|
" bool x = true;\n"
|
||||||
|
" try {\n"
|
||||||
|
" g1();\n"
|
||||||
|
" g2();\n"
|
||||||
|
" }\n"
|
||||||
|
" catch (...) {\n"
|
||||||
|
" if (x) {}\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n";
|
||||||
|
ASSERT_EQUALS(true, testValueOfXKnown(code, 10U, 1));
|
||||||
|
}
|
||||||
|
|
||||||
void valueFlowBitAnd() {
|
void valueFlowBitAnd() {
|
||||||
const char *code;
|
const char *code;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue