diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index fc7f6a448..a45f918a3 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -184,6 +184,13 @@ void CheckClass::createSymbolDatabase() break; } + // friend function + else if (tok1->previous()->str() == "friend") + { + function.isFriend = true; + break; + } + tok1 = tok1->previous(); } @@ -1867,7 +1874,7 @@ void CheckClass::checkConst() const Func & func = *it1; // does the function have a body? - if (func.type == Func::Function && func.hasBody && !func.isStatic && !func.isConst && !func.isVirtual) + if (func.type == Func::Function && func.hasBody && !func.isFriend && !func.isStatic && !func.isConst && !func.isVirtual) { // get function name const std::string functionName((func.tokenDef->isName() ? "" : "operator") + func.tokenDef->str()); diff --git a/lib/checkclass.h b/lib/checkclass.h index 6bc4ddc0b..db47e5830 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -181,6 +181,7 @@ private: isConst(false), isVirtual(false), isStatic(false), + isFriend(false), isOperator(false), type(Function) { @@ -194,6 +195,7 @@ private: bool isConst; // is const bool isVirtual; // is virtual bool isStatic; // is static + bool isFriend; // is friend bool isOperator; // is operator Type type; // constructor, destructor, ... }; diff --git a/test/testclass.cpp b/test/testclass.cpp index f133cc6cf..252c032e1 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -141,6 +141,7 @@ private: TEST_CASE(constFunc); // a function that calls const functions can be const TEST_CASE(constVirtualFunc); TEST_CASE(constIfCfg); // ticket #1881 - fp when there are #if + TEST_CASE(constFriend); // ticket #1921 - fp for friend function } // Check the operator Equal @@ -3870,6 +3871,15 @@ private: checkConst(code, &settings); ASSERT_EQUALS("", errout.str()); } + + void constFriend() // ticket #1921 + { + const char code[] = "class foo {\n" + " friend void f() { }\n" + "};"; + checkConst(code); + ASSERT_EQUALS("", errout.str()); + } }; REGISTER_TEST(TestClass)