diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 84ec6eddc..8903dab02 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -287,6 +287,9 @@ struct ForwardTraversal { analyzer->assume(condTok, !inElse, tok); if (Token::simpleMatch(tok, "} else {")) 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(), ") {")) { Token* endCond = tok->next()->link(); Token* endBlock = endCond->next()->link(); @@ -371,6 +374,14 @@ struct ForwardTraversal { } } else if (Token::simpleMatch(tok, "} else {")) { 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 {")) { Token* endBlock = tok->next()->link(); if (updateLoop(endBlock, nullptr) == Progress::Break) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 7f19dd84d..6904ed628 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -91,6 +91,7 @@ private: TEST_CASE(valueFlowForwardFunction); TEST_CASE(valueFlowForwardTernary); TEST_CASE(valueFlowForwardLambda); + TEST_CASE(valueFlowForwardTryCatch); TEST_CASE(valueFlowFwdAnalysis); @@ -2623,6 +2624,40 @@ private: 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() { const char *code;