diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 251cbe887..3bae7290c 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -458,6 +458,28 @@ static void eraseMemberAssignments(const unsigned int varId, const std::mapvariable(); + const Scope* upperScope = tok->scope(); + if (upperScope == var->scope()) + return true; + while (upperScope && upperScope->type != Scope::eTry && upperScope->type != Scope::eLambda && upperScope->nestedIn != var->scope() && upperScope->isExecutable()) { + upperScope = upperScope->nestedIn; + } + if (upperScope && upperScope->type == Scope::eTry) { + // Check all exception han + const Token* tok2 = upperScope->classEnd; + while (Token::simpleMatch(tok2, "} catch (")) { + tok2 = tok2->linkAt(2)->next(); + if (Token::findmatch(tok2, "%varid%", tok2->link(), var->declarationId())) + return false; + tok2 = tok2->link(); + } + } + return true; +} + void CheckOther::checkRedundantAssignment() { const bool printPerformance = _settings->isEnabled("performance"); @@ -541,7 +563,8 @@ void CheckOther::checkRedundantAssignment() else if (printPerformance) { const bool nonlocal = nonLocal(it->second->variable()); if (printInconclusive || !nonlocal) // see #5089 - report inconclusive only when requested - redundantAssignmentError(it->second, tok, tok->str(), nonlocal); // Inconclusive for non-local variables + if (_tokenizer->isC() || checkExceptionHandling(tok)) // see #6555 to see how exception handling might have an impact + redundantAssignmentError(it->second, tok, tok->str(), nonlocal); // Inconclusive for non-local variables } } it->second = tok; diff --git a/test/testother.cpp b/test/testother.cpp index a78d7c18d..c7a8d3fa5 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -5568,6 +5568,46 @@ private: " i = 1;\n" "}"); ASSERT_EQUALS("", errout.str()); + + // #6555 + check("void foo() {\n" + " char *p = 0;\n" + " try {\n" + " p = fred();\n" + " p = wilma();\n" + " }\n" + " catch (...) {\n" + " barney(p);\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void foo() {\n" + " char *p = 0;\n" + " try {\n" + " p = fred();\n" + " p = wilma();\n" + " }\n" + " catch (...) {\n" + " barney(x);\n" + " }\n" + "}"); + ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:5]: (performance) Variable 'p' is reassigned a value before the old one has been used.\n" + "[test.cpp:2]: (style) The scope of the variable 'p' can be reduced.\n", errout.str()); + + check("void foo() {\n" + " char *p = 0;\n" + " try {\n" + " if(z) {\n" + " p = fred();\n" + " p = wilma();\n" + " }\n" + " }\n" + " catch (...) {\n" + " barney(p);\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); } void redundantMemWrite() {