diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 733f5f047..8741df872 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2413,7 +2413,7 @@ static bool isExpressionChangedAt(const F& getExprTok, if (depth < 0) return true; if (tok->exprId() != exprid) { - if (globalvar && !tok->isKeyword() && Token::Match(tok, "%name% (")) + if (globalvar && !tok->isKeyword() && Token::Match(tok, "%name% (") && !(tok->function() && tok->function()->isAttributePure())) // TODO: Is global variable really changed by function call? return true; const bool pointer = astIsPointer(tok); diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 60dcc1e05..9baa251bd 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -513,9 +513,10 @@ void CheckCondition::multiCondition() if (tok2->astOperand2()) { ErrorPath errorPath; - if (isOverlappingCond(cond1, tok2->astOperand2(), true)) + if (isOverlappingCond(cond1, tok2->astOperand2(), true) && !isExpressionChanged(cond1, cond1, tok2->astOperand2(), mSettings, mTokenizer->isCPP())) overlappingElseIfConditionError(tok2->astOperand2(), cond1->linenr()); - else if (isOppositeCond(true, mTokenizer->isCPP(), cond1, tok2->astOperand2(), mSettings->library, true, true, &errorPath)) + else if (isOppositeCond(true, mTokenizer->isCPP(), cond1, tok2->astOperand2(), mSettings->library, true, true, &errorPath) && + !isExpressionChanged(cond1, cond1, tok2->astOperand2(), mSettings, mTokenizer->isCPP())) oppositeElseIfConditionError(cond1, tok2->astOperand2(), errorPath); } } diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 9db7e5273..dbe012a3c 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -538,6 +538,25 @@ private: " else if (!!a) {}\n" "}"); ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout.str()); + + // #11059 + check("int f();\n" + "void g() {\n" + " int i = f();\n" + " if (i == 3) {}\n" + " else if ((i = f()) == 5) {}\n" + " else if (i == 3) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("int f();\n" + "void g() {\n" + " int i = f();\n" + " if (i == 3) {}\n" + " else if ((i = f()) == 5) {}\n" + " else if (i != 3) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void checkPureFunction_(const char code[], const char* file, int line) {