diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 6b9ec6597..2d21d915a 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1580,13 +1580,37 @@ void CheckClass::checkConst() // member function? if (Token::Match(tok2, "%type% %var% (") || Token::Match(tok2, "%type% %type% %var% (") || + Token::Match(tok2, "%type% < %type% > %var% (") || + Token::Match(tok2, "%type% < %type% , %type% > %var% (") || Token::Match(tok2, "%type% :: %type% %var% (") || Token::Match(tok2, "%type% :: %type% < %type% > %var% (") || Token::Match(tok2, "%type% :: %type% < %type% , %type% > %var% (") || + Token::Match(tok2, "%type% :: %type% < %type% :: %type% < %type% > , %type% > %var% (") || + Token::Match(tok2, "%type% < %type% < %type% > , %type% > %var% (") || + Token::Match(tok2, "%type% :: %type% < %type% , %type% :: %type% < %type% > > %var% (") || + Token::Match(tok2, "%type% < %type% , %type% < %type% > > %var% (") || + Token::Match(tok2, "%type% :: %type% < %type% :: %type% < %type% > , %type% :: %type% < %type% > > %var% (") || + Token::Match(tok2, "%type% < %type% < %type% > , %type% < %type% > > %var% (") || + Token::Match(tok2, "%type% :: %type% < %type% :: %type% < %type% , %type% > , %type% > %var% (") || + Token::Match(tok2, "%type% < %type% < %type% , %type% > , %type% > %var% (") || + Token::Match(tok2, "%type% :: %type% < %type% , %type% :: %type% < %type% , %type% > > %var% (") || + Token::Match(tok2, "%type% < %type% , %type% < %type% , %type% > > %var% (") || + Token::Match(tok2, "const %type% < %type% > &|* %var% (") || + Token::Match(tok2, "const %type% < %type% , %type% > &|* %var% (") || Token::Match(tok2, "const %type% &|* %var% (") || Token::Match(tok2, "const %type% :: %type% &|*| %var% (") || Token::Match(tok2, "const %type% :: %type% < %type% > *|& %var% (") || Token::Match(tok2, "const %type% :: %type% < %type% , %type% > *|& %var% (") || + Token::Match(tok2, "const %type% :: %type% < %type% :: %type% < %type% > , %type% > *|& %var% (") || + Token::Match(tok2, "const %type% < %type% < %type% > , %type% > *|& %var% (") || + Token::Match(tok2, "const %type% :: %type% < %type% , %type% :: %type% < %type% > > *|& %var% (") || + Token::Match(tok2, "const %type% < %type% , %type% < %type% > > *|& %var% (") || + Token::Match(tok2, "const %type% :: %type% < %type% :: %type% < %type% > , %type% :: %type% < %type% > > *|& %var% (") || + Token::Match(tok2, "const %type% < %type% < %type% > , %type% < %type% > > *|& %var% (") || + Token::Match(tok2, "const %type% :: %type% < %type% :: %type% < %type% , %type% > , %type% > *|& %var% (") || + Token::Match(tok2, "const %type% < %type% < %type% , %type% > , %type% > *|& %var% (") || + Token::Match(tok2, "const %type% :: %type% < %type% , %type% :: %type% < %type% , %type% > > *|& %var% (") || + Token::Match(tok2, "const %type% < %type% , %type% < %type% , %type% > > *|& %var% (") || Token::Match(tok2, "%type% operator %any% (")) { // goto function name.. diff --git a/test/testclass.cpp b/test/testclass.cpp index a0ea8acf9..18d411f86 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -100,6 +100,7 @@ private: TEST_CASE(const11); // ticket #1529 TEST_CASE(const12); // ticket #1552 TEST_CASE(const13); // ticket #1519 + TEST_CASE(const14); TEST_CASE(constoperator); // operator< can often be const TEST_CASE(constincdec); // increment/decrement => non-const TEST_CASE(constReturnReference); @@ -2271,6 +2272,367 @@ private: "[test.cpp:5]: (style) The function 'A::GetPair' can be const\n", errout.str()); } + void const14() + { + // extends ticket 1519 + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " std::pair,double> GetPair() {return m_pair;}\n" + "private:\n" + " std::pair,double> m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " const std::pair,double>& GetPair() {return m_pair;}\n" + "private:\n" + " std::pair,double> m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " std::pair,double>& GetPair() {return m_pair;}\n" + "private:\n" + " std::pair,double> m_pair;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair GetPair() {return m_pair;}\n" + "private:\n" + " pair m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " const pair & GetPair() {return m_pair;}\n" + "private:\n" + " pair m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair & GetPair() {return m_pair;}\n" + "private:\n" + " pair m_pair;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " std::pair< int,std::vector > GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< int,std::vector > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " const std::pair< int,std::vector >& GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< int,std::vector > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " std::pair< int,std::vector >& GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< int,std::vector > m_pair;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair< int,vector > GetPair() {return m_pair;}\n" + "private:\n" + " pair< int,vector > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " const pair< int,vector >& GetPair() {return m_pair;}\n" + "private:\n" + " pair< int,vector > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair< int,vector >& GetPair() {return m_pair;}\n" + "private:\n" + " pair< int,vector > m_pair;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair< vector, int > GetPair() {return m_pair;}\n" + "private:\n" + " pair< vector, int > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " const pair< vector, int >& GetPair() {return m_pair;}\n" + "private:\n" + " pair< vector, int > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair< vector, int >& GetPair() {return m_pair;}\n" + "private:\n" + " pair< vector, int > m_pair;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " std::pair< std::vector,std::vector > GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< std::vector,std::vector > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " const std::pair< std::vector,std::vector >& GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< std::vector,std::vector > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " std::pair< std::vector,std::vector >& GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< std::vector,std::vector > m_pair;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair< vector, vector > GetPair() {return m_pair;}\n" + "private:\n" + " pair< vector, vector > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " const pair< vector, vector >& GetPair() {return m_pair;}\n" + "private:\n" + " pair< vector, vector > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair< vector, vector >& GetPair() {return m_pair;}\n" + "private:\n" + " pair< vector, vector > m_pair;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " std::pair< std::pair < int, char > , int > GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< std::pair < int, char > , int > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " const std::pair< std::pair < int, char > , int > & GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< std::pair < int, char > , int > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " std::pair< std::pair < int, char > , int > & GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< std::pair < int, char > , int > m_pair;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair< pair < int, char > , int > GetPair() {return m_pair;}\n" + "private:\n" + " pair< pair < int, char > , int > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " const pair< pair < int, char > , int > & GetPair() {return m_pair;}\n" + "private:\n" + " pair< pair < int, char > , int > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair< pair < int, char > , int > & GetPair() {return m_pair;}\n" + "private:\n" + " pair< pair < int, char > , int > m_pair;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair< int , pair < int, char > > GetPair() {return m_pair;}\n" + "private:\n" + " pair< int , pair < int, char > > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " const pair< int , pair < int, char > > & GetPair() {return m_pair;}\n" + "private:\n" + " pair< int , pair < int, char > > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " pair< int , pair < int, char > > & GetPair() {return m_pair;}\n" + "private:\n" + " pair< int , pair < int, char > > m_pair;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " std::pair< int , std::pair < int, char > > GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< int , std::pair < int, char > > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " const std::pair< int , std::pair < int, char > >& GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< int , std::pair < int, char > > m_pair;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetPair' can be const\n", errout.str()); + + checkConst("class A {\n" + "public:\n" + " A(){}\n" + " std::pair< int , std::pair < int, char > >& GetPair() {return m_pair;}\n" + "private:\n" + " std::pair< int , std::pair < int, char > > m_pair;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " vector GetVec() {return m_Vec;}\n" + "private:\n" + " vector m_Vec;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetVec' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " const vector& GetVec() {return m_Vec;}\n" + "private:\n" + " vector m_Vec;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'A::GetVec' can be const\n", errout.str()); + + checkConst("using namespace std;" + "class A {\n" + "public:\n" + " A(){}\n" + " vector& GetVec() {return m_Vec;}\n" + "private:\n" + " vector m_Vec;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + + } + // increment/decrement => not const void constincdec() {