diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 31fc8a0b5..f7c22d28d 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -433,8 +433,13 @@ bool isUniqueExpression(const Token* tok) const Scope * scope = fun->nestedIn; if (!scope) return true; + std::string returnType = fun->retType ? fun->retType->name() : fun->retDef->stringifyList(fun->tokenDef); for (const Function& f:scope->functionList) { - if (f.argumentList.size() == fun->argumentList.size() && f.name() != fun->name()) { + std::string freturnType = f.retType ? f.retType->name() : f.retDef->stringifyList(f.tokenDef); + if (f.argumentList.size() == fun->argumentList.size() && + f.type == Function::eFunction && + returnType == freturnType && + f.name() != fun->name()) { return false; } } diff --git a/lib/checkother.cpp b/lib/checkother.cpp index f8aadc015..1c4bfd86a 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1947,7 +1947,7 @@ void CheckOther::checkDuplicateExpression() tok->next()->tokType() != Token::eType && tok->next()->tokType() != Token::eName && isSameExpression(_tokenizer->isCPP(), true, tok->next(), nextAssign->next(), _settings->library, true) && - isSameExpression(_tokenizer->isCPP(), true, tok->astOperand2(), nextAssign->astOperand2(), _settings->library, false) && + isSameExpression(_tokenizer->isCPP(), true, tok->astOperand2(), nextAssign->astOperand2(), _settings->library, true) && !isUniqueExpression(tok->astOperand2())) { duplicateAssignExpressionError(var1, var2); } diff --git a/test/testother.cpp b/test/testother.cpp index a1a6ab5be..3151cd0a7 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3980,11 +3980,12 @@ private: void duplicateVarExpression() { check("int f() __attribute__((pure));\n" + "int g() __attribute__((pure));\n" "void test() {\n" " int i = f();\n" " int j = f();\n" "}"); - ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3]: (style) Same expression used in consecutive assignments of 'i' and 'j'.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:4]: (style) Same expression used in consecutive assignments of 'i' and 'j'.\n", errout.str()); check("struct Foo { int f() const; int g() const; };\n" "void test() {\n" @@ -4004,18 +4005,20 @@ private: ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:5]: (style) Same expression used in consecutive assignments of 'i' and 'j'.\n", errout.str()); check("int f() __attribute__((pure));\n" + "int g() __attribute__((pure));\n" "void test() {\n" " int i = 1 + f();\n" " int j = 1 + f();\n" "}"); - ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3]: (style) Same expression used in consecutive assignments of 'i' and 'j'.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:4]: (style) Same expression used in consecutive assignments of 'i' and 'j'.\n", errout.str()); check("int f() __attribute__((pure));\n" + "int g() __attribute__((pure));\n" "void test() {\n" " int i = f() + f();\n" " int j = f() + f();\n" "}"); - ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3]: (style) Same expression used in consecutive assignments of 'i' and 'j'.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:4]: (style) Same expression used in consecutive assignments of 'i' and 'j'.\n", errout.str()); check("int f(int) __attribute__((pure));\n" "int g(int) __attribute__((pure));\n" @@ -4058,6 +4061,7 @@ private: ASSERT_EQUALS("", errout.str()); check("int f();\n" + "int g();\n" "void test() {\n" " int i = f() || f();\n" " int j = f() && f();\n" @@ -4078,6 +4082,22 @@ private: "}"); ASSERT_EQUALS("", errout.str()); + check("struct Foo { int f() const; float g() const; };\n" + "void test() {\n" + " Foo f = Foo{};\n" + " int i = f.f();\n" + " int j = f.f();\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("struct Foo { int f(); int g(); };\n" + "void test() {\n" + " Foo f = Foo{};\n" + " int i = f.f();\n" + " int j = f.f();\n" + "}"); + ASSERT_EQUALS("", errout.str()); + check("void test() {\n" " int i = f();\n" " int j = f();\n"