diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 94dc6fc5afa..56a9489d00e 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3114,6 +3114,8 @@ static const Token* findExpressionChangedImpl(const Token* expr, if (vt->type == ValueType::ITERATOR) ++indirect; } + if (indirect == 0 && tok2->astParent() && tok2->astParent()->isUnaryOp("*")) + ++indirect; for (int i = 0; i <= indirect; ++i) { if (isExpressionChangedAt(tok, tok2, i, global, settings, depth)) return true; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index fd23e113509..7a1e1fea774 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1769,9 +1769,13 @@ void CheckOther::checkConstVariable() //Is it the right side of an initialization of a non-const reference bool usedInAssignment = false; for (const Token* tok = var->nameToken(); tok != scope->bodyEnd && tok != nullptr; tok = tok->next()) { - if (Token::Match(tok, "& %var% = %varid%", var->declarationId())) { - const Variable* refvar = tok->next()->variable(); - if (refvar && !refvar->isConst() && refvar->nameToken() == tok->next()) { + if (Token::Match(tok, "%name% = %varid%", var->declarationId())) { + const Variable* refvar = tok->variable(); + if (tok->strAt(-1) == "&" && refvar && !refvar->isConst() && refvar->nameToken() == tok) { + usedInAssignment = true; + break; + } + if (!tok->valueType() || tok->valueType()->type == ValueType::Type::RECORD) { usedInAssignment = true; break; } diff --git a/test/testother.cpp b/test/testother.cpp index c23e8c64155..a768abb647e 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4120,6 +4120,27 @@ class TestOther : public TestFixture { " std::string _s;\n" "};\n"); ASSERT_EQUALS("", errout_str()); + + check("void f(int& r) {\n" // #9761 + " o1 = r;\n" + "}\n" + "boost::optional o2;\n" + "void g(int& r) {\n" + " o2 = r;\n" + "}\n" + "struct T {\n" + " int* p;\n" + " T& operator=(int& rhs) { p = &rhs; return *this; }\n" + "};\n" + "void h(T& t, int& r) {\n" + " t = r;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("void f(std::optional& o) {\n" + " *o = 1;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void constParameterCallback() {