diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 1393d05d3..cd953ab53 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1816,12 +1816,8 @@ void CheckOther::checkDuplicateExpression() std::list constFunctions; getConstFunctions(symbolDatabase, constFunctions); - for (const Scope &scope : symbolDatabase->scopeList) { - // only check functions - if (scope.type != Scope::eFunction) - continue; - - for (const Token *tok = scope.bodyStart; tok && tok != scope.bodyEnd; tok = tok->next()) { + for (const Scope *scope : symbolDatabase->functionScopes) { + for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { if (tok->str() == "=" && Token::Match(tok->astOperand1(), "%var%")) { const Token * endStatement = Token::findsimplematch(tok, ";"); if (Token::Match(endStatement, "; %type% %var% ;")) { @@ -1848,7 +1844,7 @@ void CheckOther::checkDuplicateExpression() isSameExpression(mTokenizer->isCPP(), true, tok->astOperand2(), nextAssign->astOperand2(), mSettings->library, true, false) && tok->astOperand2()->expressionString() == nextAssign->astOperand2()->expressionString()) { bool assigned = false; - const Scope * varScope = var1->scope() ? var1->scope() : &scope; + const Scope * varScope = var1->scope() ? var1->scope() : scope; for (const Token *assignTok = Token::findsimplematch(var2, ";"); assignTok && assignTok != varScope->bodyEnd; assignTok = assignTok->next()) { if (Token::Match(assignTok, "%varid% = %var%", var1->varId()) && Token::Match(assignTok, "%var% = %varid%", var2->varId())) { assigned = true; @@ -1886,6 +1882,10 @@ void CheckOther::checkDuplicateExpression() duplicateExpressionError(tok->astOperand1(), tok->astOperand2(), tok, errorPath); } } + } else if (tok->str() == "=" && Token::simpleMatch(tok->astOperand2(), "=") && isSameExpression(mTokenizer->isCPP(), false, tok->astOperand1(), tok->astOperand2()->astOperand1(), mSettings->library, true, false)) { + if (warningEnabled && isWithoutSideEffects(mTokenizer->isCPP(), tok->astOperand1())) { + selfAssignmentError(tok, tok->astOperand1()->expressionString()); + } } else if (styleEnabled && isOppositeExpression(mTokenizer->isCPP(), tok->astOperand1(), tok->astOperand2(), mSettings->library, false, true, &errorPath) && !Token::Match(tok, "=|-|-=|/|/=") && diff --git a/test/testother.cpp b/test/testother.cpp index 8607f6b37..8292a3cac 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -2971,6 +2971,13 @@ private: "}"); ASSERT_EQUALS("[test.cpp:3]: (warning) Redundant assignment of 'a1->b' to itself.\n", errout.str()); + check("int x;\n" + "void f()\n" + "{\n" + " x = x = 3;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (warning) Redundant assignment of 'x' to itself.\n", errout.str()); + // #4073 (segmentation fault) check("void Foo::myFunc( int a )\n" "{\n"