2008-12-18 22:28:57 +01:00
/*
2009-01-21 21:04:20 +01:00
* Cppcheck - A tool for static C / C + + code analysis
2012-01-01 00:05:37 +01:00
* Copyright ( C ) 2007 - 2012 Daniel Marjamäki and Cppcheck team .
2008-12-18 22:28:57 +01:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2009-09-27 17:08:31 +02:00
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
2008-12-18 22:28:57 +01:00
*/
2009-10-25 12:49:06 +01:00
# include "tokenize.h"
# include "checkclass.h"
2008-12-18 22:28:57 +01:00
# include "testsuite.h"
# include <sstream>
extern std : : ostringstream errout ;
2011-10-13 20:53:06 +02:00
class TestClass : public TestFixture {
2008-12-18 22:28:57 +01:00
public :
TestClass ( ) : TestFixture ( " TestClass " )
{ }
private :
2011-10-13 20:53:06 +02:00
void run ( ) {
2010-03-28 10:58:03 +02:00
TEST_CASE ( virtualDestructor1 ) ; // Base class not found => no error
2009-01-05 16:49:57 +01:00
TEST_CASE ( virtualDestructor2 ) ; // Base class doesn't have a destructor
2010-03-28 10:58:03 +02:00
TEST_CASE ( virtualDestructor3 ) ; // Base class has a destructor, but it's not virtual
TEST_CASE ( virtualDestructor4 ) ; // Derived class doesn't have a destructor => no error
TEST_CASE ( virtualDestructor5 ) ; // Derived class has empty destructor => no error
2011-04-20 18:03:16 +02:00
TEST_CASE ( virtualDestructor6 ) ; // only report error if base class pointer that points at derived class is deleted
2009-05-06 22:22:26 +02:00
TEST_CASE ( virtualDestructorProtected ) ;
2009-08-04 21:23:22 +02:00
TEST_CASE ( virtualDestructorInherited ) ;
2009-08-10 16:58:13 +02:00
TEST_CASE ( virtualDestructorTemplate ) ;
2009-01-14 20:34:10 +01:00
2012-09-17 17:59:35 +02:00
TEST_CASE ( copyConstructor ) ;
2009-02-21 14:35:55 +01:00
TEST_CASE ( noConstructor1 ) ;
TEST_CASE ( noConstructor2 ) ;
2009-12-19 17:58:52 +01:00
TEST_CASE ( noConstructor3 ) ;
TEST_CASE ( noConstructor4 ) ;
2010-08-09 17:50:26 +02:00
TEST_CASE ( noConstructor5 ) ;
2009-08-09 19:57:48 +02:00
TEST_CASE ( operatorEq1 ) ;
2011-04-01 01:40:28 +02:00
TEST_CASE ( operatorEq2 ) ;
2011-08-28 17:14:15 +02:00
TEST_CASE ( operatorEq3 ) ; // ticket #3051
2011-09-15 01:04:06 +02:00
TEST_CASE ( operatorEq4 ) ; // ticket #3114
2011-12-14 15:37:43 +01:00
TEST_CASE ( operatorEq5 ) ; // ticket #3296
2010-01-29 16:04:27 +01:00
TEST_CASE ( operatorEqRetRefThis1 ) ;
TEST_CASE ( operatorEqRetRefThis2 ) ; // ticket #1323
2010-02-17 22:46:03 +01:00
TEST_CASE ( operatorEqRetRefThis3 ) ; // ticket #1405
2010-02-25 07:26:59 +01:00
TEST_CASE ( operatorEqRetRefThis4 ) ; // ticket #1451
2010-04-01 16:40:12 +02:00
TEST_CASE ( operatorEqRetRefThis5 ) ; // ticket #1550
2011-01-21 19:54:41 +01:00
TEST_CASE ( operatorEqRetRefThis6 ) ; // ticket #2479
2010-01-06 19:04:15 +01:00
TEST_CASE ( operatorEqToSelf1 ) ; // single class
TEST_CASE ( operatorEqToSelf2 ) ; // nested class
TEST_CASE ( operatorEqToSelf3 ) ; // multiple inheritance
TEST_CASE ( operatorEqToSelf4 ) ; // nested class with multiple inheritance
2010-01-12 21:36:40 +01:00
TEST_CASE ( operatorEqToSelf5 ) ; // ticket # 1233
2010-03-31 17:09:59 +02:00
TEST_CASE ( operatorEqToSelf6 ) ; // ticket # 1550
2010-09-11 08:23:30 +02:00
TEST_CASE ( operatorEqToSelf7 ) ;
2010-11-09 06:58:19 +01:00
TEST_CASE ( operatorEqToSelf8 ) ; // ticket #2179
2011-02-20 02:02:16 +01:00
TEST_CASE ( operatorEqToSelf9 ) ; // ticket #2592
2009-09-02 22:32:15 +02:00
TEST_CASE ( memsetOnStruct ) ;
2010-07-26 16:46:37 +02:00
TEST_CASE ( memsetVector ) ;
2009-09-02 22:32:15 +02:00
TEST_CASE ( memsetOnClass ) ;
2009-09-12 15:25:02 +02:00
TEST_CASE ( this_subtraction ) ; // warn about "this-x"
2010-01-23 09:19:22 +01:00
// can member function be made const
TEST_CASE ( const1 ) ;
2010-02-08 07:25:19 +01:00
TEST_CASE ( const2 ) ;
TEST_CASE ( const3 ) ;
2010-03-05 17:06:25 +01:00
TEST_CASE ( const4 ) ;
2010-03-12 18:30:20 +01:00
TEST_CASE ( const5 ) ; // ticket #1482
2010-03-13 08:06:20 +01:00
TEST_CASE ( const6 ) ; // ticket #1491
2010-03-16 07:31:40 +01:00
TEST_CASE ( const7 ) ;
2010-03-23 07:34:34 +01:00
TEST_CASE ( const8 ) ; // ticket #1517
2010-03-23 07:37:20 +01:00
TEST_CASE ( const9 ) ; // ticket #1515
2010-03-26 16:30:30 +01:00
TEST_CASE ( const10 ) ; // ticket #1522
2010-03-26 18:16:33 +01:00
TEST_CASE ( const11 ) ; // ticket #1529
2010-03-26 19:06:00 +01:00
TEST_CASE ( const12 ) ; // ticket #1552
2010-03-26 20:14:31 +01:00
TEST_CASE ( const13 ) ; // ticket #1519
2010-03-27 20:41:17 +01:00
TEST_CASE ( const14 ) ;
2010-03-28 15:56:13 +02:00
TEST_CASE ( const15 ) ;
2010-04-01 16:59:35 +02:00
TEST_CASE ( const16 ) ; // ticket #1551
2010-04-01 17:01:52 +02:00
TEST_CASE ( const17 ) ; // ticket #1552
2012-08-01 19:24:38 +02:00
TEST_CASE ( const18 ) ;
2010-04-18 07:53:39 +02:00
TEST_CASE ( const19 ) ; // ticket #1612
2010-04-18 15:40:31 +02:00
TEST_CASE ( const20 ) ; // ticket #1602
2010-05-16 20:26:32 +02:00
TEST_CASE ( const21 ) ; // ticket #1683
2010-05-20 06:52:59 +02:00
TEST_CASE ( const22 ) ;
2010-05-20 17:45:10 +02:00
TEST_CASE ( const23 ) ; // ticket #1699
2010-05-25 06:55:49 +02:00
TEST_CASE ( const24 ) ; // ticket #1708
2010-06-03 12:51:42 +02:00
TEST_CASE ( const25 ) ; // ticket #1724
2010-07-13 08:01:57 +02:00
TEST_CASE ( const26 ) ; // ticket #1847
2010-07-19 08:40:46 +02:00
TEST_CASE ( const27 ) ; // ticket #1882
2010-07-19 13:16:11 +02:00
TEST_CASE ( const28 ) ; // ticket #1883
2010-08-09 17:54:16 +02:00
TEST_CASE ( const29 ) ; // ticket #1922
2010-08-10 07:48:09 +02:00
TEST_CASE ( const30 ) ;
2010-08-14 08:16:53 +02:00
TEST_CASE ( const31 ) ;
2010-08-15 08:30:21 +02:00
TEST_CASE ( const32 ) ; // ticket #1905 - member array is assigned
2010-08-20 07:28:31 +02:00
TEST_CASE ( const33 ) ;
2010-08-20 19:47:41 +02:00
TEST_CASE ( const34 ) ; // ticket #1964
2010-08-31 17:57:42 +02:00
TEST_CASE ( const35 ) ; // ticket #2001
2010-09-01 06:18:09 +02:00
TEST_CASE ( const36 ) ; // ticket #2003
2010-10-12 07:57:09 +02:00
TEST_CASE ( const37 ) ; // ticket #2081 and #2085
2010-10-27 19:25:34 +02:00
TEST_CASE ( const38 ) ; // ticket #2135
2010-11-06 20:27:12 +01:00
TEST_CASE ( const39 ) ;
2010-11-25 07:15:33 +01:00
TEST_CASE ( const40 ) ; // ticket #2228
2010-11-30 19:40:32 +01:00
TEST_CASE ( const41 ) ; // ticket #2255
2010-12-07 19:42:30 +01:00
TEST_CASE ( const42 ) ; // ticket #2282
2010-12-30 01:29:09 +01:00
TEST_CASE ( const43 ) ; // ticket #2377
2011-02-21 02:01:54 +01:00
TEST_CASE ( const44 ) ; // ticket #2595
2011-03-20 17:53:37 +01:00
TEST_CASE ( const45 ) ; // ticket #2664
2011-03-20 18:29:52 +01:00
TEST_CASE ( const46 ) ; // ticket #2636
2011-03-23 00:23:36 +01:00
TEST_CASE ( const47 ) ; // ticket #2670
2011-03-24 01:19:32 +01:00
TEST_CASE ( const48 ) ; // ticket #2672
2011-06-04 04:00:27 +02:00
TEST_CASE ( const49 ) ; // ticket #2795
2011-07-27 17:23:22 +02:00
TEST_CASE ( const50 ) ; // ticket #2943
2011-08-23 02:34:00 +02:00
TEST_CASE ( const51 ) ; // ticket #3040
2011-12-15 20:18:52 +01:00
TEST_CASE ( const52 ) ; // ticket #3048
TEST_CASE ( const53 ) ; // ticket #3049
TEST_CASE ( const54 ) ; // ticket #3052
TEST_CASE ( const55 ) ;
TEST_CASE ( const56 ) ; // ticket #3149
2012-05-17 11:15:21 +02:00
TEST_CASE ( const57 ) ; // tickets #2669 and #2477
2012-05-16 21:36:05 +02:00
TEST_CASE ( const58 ) ; // ticket #2698
2012-05-17 10:05:36 +02:00
TEST_CASE ( const_handleDefaultParameters ) ;
2012-05-17 10:49:52 +02:00
TEST_CASE ( const_passThisToMemberOfOtherClass ) ;
2010-12-30 22:57:43 +01:00
TEST_CASE ( assigningPointerToPointerIsNotAConstOperation ) ;
2011-01-01 01:19:32 +01:00
TEST_CASE ( assigningArrayElementIsNotAConstOperation ) ;
2010-04-02 22:03:07 +02:00
TEST_CASE ( constoperator1 ) ; // operator< can often be const
2011-12-15 20:18:52 +01:00
TEST_CASE ( constoperator2 ) ; // operator<<
2010-08-30 17:14:20 +02:00
TEST_CASE ( constoperator3 ) ;
2010-12-29 20:22:06 +01:00
TEST_CASE ( constoperator4 ) ;
2012-03-24 13:48:33 +01:00
TEST_CASE ( constoperator5 ) ; // ticket #3252
2010-01-24 13:33:30 +01:00
TEST_CASE ( constincdec ) ; // increment/decrement => non-const
2011-03-27 19:59:12 +02:00
TEST_CASE ( constassign1 ) ;
TEST_CASE ( constassign2 ) ;
2011-03-26 03:37:32 +01:00
TEST_CASE ( constincdecarray ) ; // increment/decrement array element => non-const
2011-03-26 04:02:13 +01:00
TEST_CASE ( constassignarray ) ;
2010-01-25 21:40:57 +01:00
TEST_CASE ( constReturnReference ) ;
2010-02-20 09:55:51 +01:00
TEST_CASE ( constDelete ) ; // delete member variable => not const
2010-02-21 10:19:28 +01:00
TEST_CASE ( constLPVOID ) ; // a function that returns LPVOID can't be const
2010-04-19 21:18:53 +02:00
TEST_CASE ( constFunc ) ; // a function that calls const functions can be const
2010-07-18 10:18:41 +02:00
TEST_CASE ( constVirtualFunc ) ;
2010-08-07 13:08:36 +02:00
TEST_CASE ( constIfCfg ) ; // ticket #1881 - fp when there are #if
2010-08-07 16:08:44 +02:00
TEST_CASE ( constFriend ) ; // ticket #1921 - fp for friend function
2011-12-14 21:11:40 +01:00
TEST_CASE ( constUnion ) ; // ticket #2111 - fp when there is a union
2011-09-28 03:07:37 +02:00
2012-05-18 16:54:58 +02:00
TEST_CASE ( initializerListOrder ) ;
TEST_CASE ( initializerListUsage ) ;
2009-08-09 19:57:48 +02:00
}
2012-09-17 17:59:35 +02:00
void checkCopyConstructor ( const char code [ ] ) {
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
settings . addEnabled ( " style " ) ;
// Tokenize..
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
tokenizer . simplifyTokenList ( ) ;
// Check..
CheckClass checkClass ( & tokenizer , & settings , this ) ;
checkClass . copyconstructors ( ) ;
}
void copyConstructor ( ) {
checkCopyConstructor ( " class F \n "
" { \n "
" public: \n "
" char *c,*p,*d; \n "
" F(const F &f) : p(f.p), c(f.c) \n "
" { \n "
" p=(char *)malloc(strlen(f.p)+1); \n "
" strcpy(p,f.p); \n "
" } \n "
" F(char *str) \n "
" { \n "
" p=(char *)malloc(strlen(str)+1); \n "
" strcpy(p,str); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (style) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory. \n " , errout . str ( ) ) ;
checkCopyConstructor ( " class F { \n "
" char *p; \n "
" F(const F &f) { \n "
" p = f.p; \n "
" } \n "
" F(char *str) { \n "
" p = malloc(strlen(str)+1); \n "
" } \n "
" }; " ) ;
2012-09-17 18:10:11 +02:00
TODO_ASSERT_EQUALS ( " [test.cpp:4]: (style) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory. \n "
" [test.cpp:3] -> [test.cpp:7]: (warning) Copy constructor does not allocate memory for member 'p' although memory has been allocated in other constructors. \n " ,
" [test.cpp:4]: (style) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory. \n "
, errout . str ( ) ) ;
2012-09-17 17:59:35 +02:00
checkCopyConstructor ( " class F \n "
" { \n "
" public: \n "
" char *c,*p,*d; \n "
" F(const F &f) :p(f.p) \n "
" { \n "
" } \n "
" F(char *str) \n "
" { \n "
" p=(char *)malloc(strlen(str)+1); \n "
" strcpy(p,str); \n "
" } \n "
" }; " ) ;
2012-09-17 18:10:11 +02:00
TODO_ASSERT_EQUALS ( " [test.cpp:5]: (style) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory. \n "
" [test.cpp:5] -> [test.cpp:10]: (warning) Copy constructor does not allocate memory for member 'p' although memory has been allocated in other constructors. \n " ,
" [test.cpp:5]: (style) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory. \n "
, errout . str ( ) ) ;
2012-09-17 17:59:35 +02:00
checkCopyConstructor ( " class kalci \n "
" { \n "
" public: \n "
" char *c,*p,*d; \n "
" kalci() \n "
" { \n "
" p=(char *)malloc(100); \n "
" strcpy(p, \" hello \" ); \n "
" c=(char *)malloc(100); \n "
" strcpy(p, \" hello \" ); \n "
" d=(char *)malloc(100); \n "
" strcpy(p, \" hello \" ); \n "
" } \n "
" kalci(const kalci &f) \n "
" { \n "
" p=(char *)malloc(strlen(str)+1); \n "
" strcpy(p,f.p); \n "
" c=(char *)malloc(strlen(str)+1); \n "
" strcpy(p,f.p); \n "
" d=(char *)malloc(strlen(str)+1); \n "
" strcpy(p,f.p); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkCopyConstructor ( " class F \n "
" { \n "
" public: \n "
" char *c,*p,*d; \n "
" F(char *str,char *st,char *string) \n "
" { \n "
" p=(char *)malloc(100); \n "
" strcpy(p,str); \n "
" c=(char *)malloc(100); \n "
" strcpy(p,st); \n "
" d=(char *)malloc(100); \n "
" strcpy(p,string); \n "
" } \n "
" F(const F &f) \n "
" { \n "
" p=(char *)malloc(strlen(str)+1); \n "
" strcpy(p,f.p); \n "
" c=(char *)malloc(strlen(str)+1); \n "
" strcpy(p,f.p); \n "
" } \n "
" }; " ) ;
2012-09-17 18:10:11 +02:00
TODO_ASSERT_EQUALS ( " [test.cpp:14] -> [test.cpp:11]: (warning) Copy constructor does not allocate memory for member 'd' although memory has been allocated in other constructors. \n " , " " , errout . str ( ) ) ;
2012-09-17 17:59:35 +02:00
checkCopyConstructor ( " class F { \n "
" char *c; \n "
" F(char *str,char *st,char *string) { \n "
" p=(char *)malloc(100); \n "
" } \n "
" F(const F &f) \n "
" : p(malloc(size)) \n "
" { \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkCopyConstructor ( " class F { \n "
" char *c; \n "
" F(char *str,char *st,char *string) \n "
" : p(malloc(size)) \n "
" { \n "
" } \n "
" F(const F &f) \n "
" { \n "
" } \n "
" }; " ) ;
TODO_ASSERT_EQUALS ( " [test.cpp:7] -> [test.cpp:4]: (warning) Copy constructor does not allocate memory for member 'd' although memory has been allocated in other constructors. \n " , " " , errout . str ( ) ) ;
checkCopyConstructor ( " class F \n "
" { \n "
" public: \n "
" char *c,*p,*d; \n "
" F() \n "
" { \n "
" p=(char *)malloc(100); \n "
" c=(char *)malloc(100); \n "
" d=(char*)malloc(100); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " [test.cpp:1]: (style) 'class F' does not have a copy constructor which is required since the class contains a pointer to allocated memory. \n " , errout . str ( ) ) ;
checkCopyConstructor ( " class F \n "
" { \n "
" public: \n "
" char *c; \n "
" const char *p,*d; \n "
" F(char *str,char *st,char *string) \n "
" { \n "
" p=str; \n "
" d=st; \n "
" c=(char *)malloc(strlen(string)+1); \n "
" strcpy(d,string); \n "
" } \n "
" F(const F &f) \n "
" { \n "
" p=f.p; \n "
" d=f.d; \n "
" c=(char *)malloc(strlen(str)+1); \n "
" strcpy(d,f.p); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkCopyConstructor ( " class F : E \n "
" { \n "
" char *p; \n "
" F() { \n "
" p = malloc(100); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkCopyConstructor ( " class E { E(E&); }; \n " // non-copyable
" class F : E \n "
" { \n "
" char *p; \n "
" F() { \n "
" p = malloc(100); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkCopyConstructor ( " class E {}; \n "
" class F : E { \n "
" char *p; \n "
" F() { \n "
" p = malloc(100); \n "
" } \n "
" }; " ) ;
TODO_ASSERT_EQUALS ( " [test.cpp:2]: (style) 'class F' does not have a copy constructor which is required since the class contains a pointer to allocated memory. \n " , " " , errout . str ( ) ) ;
checkCopyConstructor ( " class F { \n "
" char *p; \n "
" F() { \n "
" p = malloc(100); \n "
" } \n "
" F(F& f); \n " // non-copyable
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-08-09 19:57:48 +02:00
// Check the operator Equal
2011-10-13 20:53:06 +02:00
void checkOpertorEq ( const char code [ ] ) {
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
2011-08-07 09:28:08 +02:00
settings . addEnabled ( " style " ) ;
2011-11-21 08:00:10 +01:00
settings . inconclusive = true ;
2010-12-01 18:00:55 +01:00
2009-08-09 19:57:48 +02:00
// Tokenize..
2010-12-01 18:00:55 +01:00
Tokenizer tokenizer ( & settings , this ) ;
2009-08-09 19:57:48 +02:00
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
tokenizer . simplifyTokenList ( ) ;
// Check..
CheckClass checkClass ( & tokenizer , & settings , this ) ;
checkClass . operatorEq ( ) ;
}
2011-10-13 20:53:06 +02:00
void operatorEq1 ( ) {
2009-08-09 19:57:48 +02:00
checkOpertorEq ( " class A \n "
" { \n "
" public: \n "
2009-08-24 17:15:29 +02:00
" void goo() {} "
2009-12-31 13:44:03 +01:00
" void operator=(const A&); \n "
2009-08-09 19:57:48 +02:00
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) 'A::operator=' should return 'A &'. \n " , errout . str ( ) ) ;
2009-08-09 19:57:48 +02:00
checkOpertorEq ( " class A \n "
" { \n "
" private: \n "
2009-12-31 13:44:03 +01:00
" void operator=(const A&); \n "
2009-08-09 19:57:48 +02:00
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEq ( " class A \n "
" { \n "
2009-12-31 13:44:03 +01:00
" void operator=(const A&); \n "
2009-08-09 19:57:48 +02:00
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEq ( " class A \n "
" { \n "
" public: \n "
" void goo() {} \n "
" private: \n "
2009-12-31 13:44:03 +01:00
" void operator=(const A&); \n "
2009-08-09 19:57:48 +02:00
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-29 07:48:37 +01:00
checkOpertorEq ( " class A \n "
" { \n "
" public: \n "
2009-12-31 13:44:03 +01:00
" void operator=(const A&); \n "
2009-12-29 07:48:37 +01:00
" }; \n "
" class B \n "
" { \n "
" public: \n "
2009-12-31 13:44:03 +01:00
" void operator=(const B&); \n "
2009-12-29 07:48:37 +01:00
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) 'A::operator=' should return 'A &'. \n "
" [test.cpp:9]: (style) 'B::operator=' should return 'B &'. \n " , errout . str ( ) ) ;
2009-12-29 07:48:37 +01:00
2009-12-30 18:40:02 +01:00
checkOpertorEq ( " struct A \n "
" { \n "
2009-12-31 13:44:03 +01:00
" void operator=(const A&); \n "
2009-12-30 18:40:02 +01:00
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) 'A::operator=' should return 'A &'. \n " , errout . str ( ) ) ;
2011-04-01 01:40:28 +02:00
}
2011-10-13 20:53:06 +02:00
void operatorEq2 ( ) {
2011-04-01 01:40:28 +02:00
checkOpertorEq ( " class A \n "
" { \n "
" public: \n "
" void * operator=(const A&); \n "
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) 'A::operator=' should return 'A &'. \n " , errout . str ( ) ) ;
2011-04-01 01:40:28 +02:00
checkOpertorEq ( " class A \n "
" { \n "
" public: \n "
" A * operator=(const A&); \n "
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) 'A::operator=' should return 'A &'. \n " , errout . str ( ) ) ;
2011-04-01 01:40:28 +02:00
checkOpertorEq ( " class A \n "
" { \n "
" public: \n "
" const A & operator=(const A&); \n "
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) 'A::operator=' should return 'A &'. \n " , errout . str ( ) ) ;
2011-04-01 01:40:28 +02:00
checkOpertorEq ( " class A \n "
" { \n "
" public: \n "
" B & operator=(const A&); \n "
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) 'A::operator=' should return 'A &'. \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2011-10-13 20:53:06 +02:00
void operatorEq3 ( ) { // ticket #3051
2011-08-28 17:14:15 +02:00
checkOpertorEq ( " class A \n "
" { \n "
" public: \n "
" A * operator=(const A*); \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void operatorEq4 ( ) { // ticket #3114 (infinite loop)
2011-09-15 01:04:06 +02:00
checkOpertorEq ( " struct A { \n "
" A& operator=(A const& a) { return operator=(&a); } \n "
" A& operator=(const A*) { return *this; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-12-14 15:37:43 +01:00
void operatorEq5 ( ) { // ticket #3296 (virtual operator)
checkOpertorEq (
" class A { \n "
" virtual A& operator=(const A &a) {return *this}; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-12-31 13:44:03 +01:00
// Check that operator Equal returns reference to this
2011-10-13 20:53:06 +02:00
void checkOpertorEqRetRefThis ( const char code [ ] ) {
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
2011-08-07 09:28:08 +02:00
settings . addEnabled ( " style " ) ;
2010-12-01 18:00:55 +01:00
2009-12-31 13:44:03 +01:00
// Tokenize..
2010-12-01 18:00:55 +01:00
Tokenizer tokenizer ( & settings , this ) ;
2009-12-31 13:44:03 +01:00
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
tokenizer . simplifyTokenList ( ) ;
// Check..
CheckClass checkClass ( & tokenizer , & settings , this ) ;
checkClass . operatorEqRetRefThis ( ) ;
}
2011-10-13 20:53:06 +02:00
void operatorEqRetRefThis1 ( ) {
2009-12-31 13:44:03 +01:00
checkOpertorEqRetRefThis (
" class A \n "
" { \n "
" public: \n "
" A & operator=(const A &a) { return *this; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqRetRefThis (
" class A \n "
" { \n "
" public: \n "
" A & operator=(const A &a) { return a; } \n "
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) 'operator=' should return reference to 'this' instance. \n " , errout . str ( ) ) ;
2009-12-31 13:44:03 +01:00
checkOpertorEqRetRefThis (
" class A \n "
" { \n "
" public: \n "
" A & operator=(const A &); \n "
" }; \n "
" A & A::operator=(const A &a) { return *this; } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqRetRefThis (
" class A \n "
" { \n "
" public: \n "
" A & operator=(const A &a); \n "
" }; \n "
" A & A::operator=(const A &a) { return *this; } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqRetRefThis (
" class A \n "
" { \n "
" public: \n "
2010-07-26 16:46:37 +02:00
" A & operator=(const A &); \n "
2009-12-31 13:44:03 +01:00
" }; \n "
" A & A::operator=(const A &a) { return a; } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (style) 'operator=' should return reference to 'this' instance. \n " , errout . str ( ) ) ;
2009-12-31 13:44:03 +01:00
checkOpertorEqRetRefThis (
" class A \n "
" { \n "
" public: \n "
2010-07-26 16:46:37 +02:00
" A & operator=(const A &a); \n "
2009-12-31 13:44:03 +01:00
" }; \n "
" A & A::operator=(const A &a) { return a; } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (style) 'operator=' should return reference to 'this' instance. \n " , errout . str ( ) ) ;
2009-12-31 13:44:03 +01:00
checkOpertorEqRetRefThis (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
" B & operator=(const B &b) { return *this; } \n "
" }; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqRetRefThis (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
" B & operator=(const B &b) { return b; } \n "
" }; \n "
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (style) 'operator=' should return reference to 'this' instance. \n " , errout . str ( ) ) ;
2009-12-31 13:44:03 +01:00
checkOpertorEqRetRefThis (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
" B & operator=(const B &); \n "
" }; \n "
" }; \n "
" A::B & A::B::operator=(const A::B &b) { return *this; } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqRetRefThis (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
" B & operator=(const B &); \n "
" }; \n "
" }; \n "
" A::B & A::B::operator=(const A::B &b) { return b; } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:10]: (style) 'operator=' should return reference to 'this' instance. \n " , errout . str ( ) ) ;
2009-12-31 13:44:03 +01:00
}
2011-10-13 20:53:06 +02:00
void operatorEqRetRefThis2 ( ) {
2010-01-29 16:04:27 +01:00
// ticket # 1323
checkOpertorEqRetRefThis (
" class szp \n "
" { \n "
" szp &operator =(int *other) {}; \n "
" }; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) 'operator=' should return reference to 'this' instance. \n " , errout . str ( ) ) ;
2010-04-06 18:26:29 +02:00
checkOpertorEqRetRefThis (
" class szp \n "
" { \n "
" szp &operator =(int *other); \n "
" }; \n "
2010-07-26 16:46:37 +02:00
" szp &szp::operator =(int *other) {} " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (style) 'operator=' should return reference to 'this' instance. \n " , errout . str ( ) ) ;
2010-01-29 16:04:27 +01:00
}
2011-10-13 20:53:06 +02:00
void operatorEqRetRefThis3 ( ) {
2010-02-17 22:46:03 +01:00
// ticket # 1405
checkOpertorEqRetRefThis (
" class A { \n "
" public: \n "
2011-09-13 07:55:47 +02:00
" inline A &operator =(int *other) { return (*this); }; \n "
" inline A &operator =(long *other) { return (*this = 0); }; \n "
2010-02-17 22:46:03 +01:00
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-06 18:26:29 +02:00
checkOpertorEqRetRefThis (
" class A { \n "
" public: \n "
" A &operator =(int *other); \n "
" A &operator =(long *other); \n "
" }; \n "
2011-09-13 07:55:47 +02:00
" A &A::operator =(int *other) { return (*this); }; \n "
" A &A::operator =(long *other) { return (*this = 0); }; " ) ;
2010-04-06 18:26:29 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqRetRefThis (
" class A { \n "
" public: \n "
2011-09-13 07:55:47 +02:00
" inline A &operator =(int *other) { return (*this); }; \n "
2010-04-06 18:26:29 +02:00
" inline A &operator =(long *other) { return operator = (*(int *)other); }; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqRetRefThis (
" class A { \n "
" public: \n "
" A &operator =(int *other); \n "
" A &operator =(long *other); \n "
" }; \n "
2011-09-13 07:55:47 +02:00
" A &A::operator =(int *other) { return (*this); }; \n "
2010-04-06 18:26:29 +02:00
" A &A::operator =(long *other) { return operator = (*(int *)other); }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-03-15 08:19:30 +01:00
checkOpertorEqRetRefThis (
" class A { \n "
" public: \n "
" A &operator =(int *other); \n "
" A &operator =(long *other); \n "
" }; \n "
2011-09-13 07:55:47 +02:00
" A &A::operator =(int *other) { return (*this); }; \n "
2011-03-15 08:19:30 +01:00
" A &A::operator =(long *other) { return this->operator = (*(int *)other); }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-02-17 22:46:03 +01:00
}
2010-02-25 07:26:59 +01:00
2011-10-13 20:53:06 +02:00
void operatorEqRetRefThis4 ( ) {
2010-02-25 07:26:59 +01:00
// ticket # 1451
checkOpertorEqRetRefThis (
" P& P::operator = (const P& pc) \n "
" { \n "
" return (P&)(*this += pc); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-02-17 22:46:03 +01:00
2011-10-13 20:53:06 +02:00
void operatorEqRetRefThis5 ( ) {
2010-04-01 16:40:12 +02:00
// ticket # 1550
checkOpertorEqRetRefThis (
" class A { \n "
" public: \n "
" A & operator=(const A &a) { } \n "
" }; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) 'operator=' should return reference to 'this' instance. \n " , errout . str ( ) ) ;
2010-04-06 18:26:29 +02:00
checkOpertorEqRetRefThis (
" class A { \n "
" public: \n "
" A & operator=(const A &a); \n "
" }; \n "
" A & A :: operator=(const A &a) { } " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (style) 'operator=' should return reference to 'this' instance. \n " , errout . str ( ) ) ;
2010-04-01 16:40:12 +02:00
}
2011-10-13 20:53:06 +02:00
void operatorEqRetRefThis6 ( ) { // ticket #2478 (segmentation fault)
2011-01-21 19:54:41 +01:00
checkOpertorEqRetRefThis (
" class UString { \n "
" public: \n "
" UString& assign( const char* c_str ); \n "
" UString& operator=( const UString& s ); \n "
" }; \n "
" UString& UString::assign( const char* c_str ) { \n "
2011-02-05 12:53:28 +01:00
" std::string tmp( c_str ); \n "
" return assign( tmp ); \n "
2011-01-21 19:54:41 +01:00
" } \n "
" UString& UString::operator=( const UString& s ) { \n "
2011-02-05 12:53:28 +01:00
" return assign( s ); \n "
2011-01-21 19:54:41 +01:00
" } \n " ) ;
}
2009-12-31 13:44:03 +01:00
// Check that operator Equal checks for assignment to self
2011-10-13 20:53:06 +02:00
void checkOpertorEqToSelf ( const char code [ ] ) {
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
2011-08-07 09:28:08 +02:00
settings . addEnabled ( " style " ) ;
2010-12-01 18:00:55 +01:00
2009-12-31 13:44:03 +01:00
// Tokenize..
2010-12-01 18:00:55 +01:00
Tokenizer tokenizer ( & settings , this ) ;
2009-12-31 13:44:03 +01:00
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
tokenizer . simplifyTokenList ( ) ;
// Check..
CheckClass checkClass ( & tokenizer , & settings , this ) ;
checkClass . operatorEqToSelf ( ) ;
}
2011-10-13 20:53:06 +02:00
void operatorEqToSelf1 ( ) {
2010-01-03 08:26:02 +01:00
// this test has an assignment test but it is not needed
2009-12-31 13:44:03 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
2010-01-03 08:26:02 +01:00
" A & operator=(const A &a) { if (&a != this) { } return *this; } \n "
2009-12-31 13:44:03 +01:00
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-03 08:26:02 +01:00
// this test doesn't have an assignment test but it is not needed
2009-12-31 13:44:03 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" A & operator=(const A &a) { return *this; } \n "
" }; \n " ) ;
2010-01-03 08:26:02 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-31 14:03:35 +01:00
2010-01-03 08:26:02 +01:00
// this test needs an assignment test and has it
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a) \n "
" { \n "
" if (&a != this) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// this class needs an assignment test but doesn't have it
2009-12-31 14:03:35 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" return *this; \n "
" } \n "
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. \n " , errout . str ( ) ) ;
2009-12-31 13:44:03 +01:00
2010-01-03 08:26:02 +01:00
// this test has an assignment test but doesn't need it
2009-12-31 13:44:03 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" A & operator=(const A &); \n "
" }; \n "
2010-01-03 08:26:02 +01:00
" A & A::operator=(const A &a) { if (&a != this) { } return *this; } \n " ) ;
2009-12-31 13:44:03 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-03 08:26:02 +01:00
// this test doesn't have an assignment test but doesn't need it
2009-12-31 13:44:03 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
2010-08-09 17:50:26 +02:00
" A & operator=(const A &); \n "
2009-12-31 13:44:03 +01:00
" }; \n "
2010-01-03 08:26:02 +01:00
" A & A::operator=(const A &a) { return *this; } \n " ) ;
2009-12-31 13:44:03 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-03 08:26:02 +01:00
// this test needs an assignment test and has it
2009-12-31 13:44:03 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
2010-01-03 08:26:02 +01:00
" char *s; \n "
" A & operator=(const A &); \n "
2009-12-31 13:44:03 +01:00
" }; \n "
2010-08-09 17:50:26 +02:00
" A & A::operator=(const A &a) \n "
2010-01-03 08:26:02 +01:00
" { \n "
" if (&a != this) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-31 13:44:03 +01:00
2010-12-15 18:45:53 +01:00
// this test needs an assignment test but doesn’ t have it
2009-12-31 13:44:03 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
2010-01-03 08:26:02 +01:00
" char *s; \n "
" A & operator=(const A &); \n "
2009-12-31 13:44:03 +01:00
" }; \n "
2010-08-09 17:50:26 +02:00
" A & A::operator=(const A &a) \n "
2010-01-03 08:26:02 +01:00
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" return *this; \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. \n " , errout . str ( ) ) ;
2010-01-05 21:55:33 +01:00
// ticket #1224
checkOpertorEqToSelf (
" const SubTree &SubTree::operator= (const SubTree &b) \n "
" { \n "
" CodeTree *oldtree = tree; \n "
" tree = new CodeTree(*b.tree); \n "
" delete oldtree; \n "
" return *this; \n "
" } \n "
" const SubTree &SubTree::operator= (const CodeTree &b) \n "
" { \n "
" CodeTree *oldtree = tree; \n "
" tree = new CodeTree(b); \n "
" delete oldtree; \n "
" return *this; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-03 08:26:02 +01:00
}
2009-12-31 13:44:03 +01:00
2011-10-13 20:53:06 +02:00
void operatorEqToSelf2 ( ) {
2010-01-03 08:26:02 +01:00
// this test has an assignment test but doesn't need it
2009-12-31 13:44:03 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
2010-01-03 08:26:02 +01:00
" B & operator=(const B &b) { if (&b != this) { } return *this; } \n "
2009-12-31 13:44:03 +01:00
" }; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-03 08:26:02 +01:00
// this test doesn't have an assignment test but doesn't need it
2009-12-31 13:44:03 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
2010-01-03 08:26:02 +01:00
" B & operator=(const B &b) { return *this; } \n "
2009-12-31 13:44:03 +01:00
" }; \n "
" }; \n " ) ;
2010-01-03 08:26:02 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-31 13:44:03 +01:00
2010-01-03 08:26:02 +01:00
// this test needs an assignment test but has it
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
" char *s; \n "
" B & operator=(const B &b) \n "
" { \n "
" if (&b != this) \n "
" { \n "
" } \n "
" return *this; \n "
" } \n "
" }; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// this test needs an assignment test but doesn't have it
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
" char *s; \n "
" B & operator=(const B &b) \n "
" { \n "
" free(s); \n "
" s = strdup(b.s); \n "
" return *this; \n "
" } \n "
" }; \n "
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. \n " , errout . str ( ) ) ;
2010-01-03 08:26:02 +01:00
// this test has an assignment test but doesn't need it
2009-12-31 13:44:03 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
" B & operator=(const B &); \n "
" }; \n "
" }; \n "
2010-01-03 08:26:02 +01:00
" A::B & A::B::operator=(const A::B &b) { if (&b != this) { } return *this; } \n " ) ;
2009-12-31 13:44:03 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-03 08:26:02 +01:00
// this test doesn't have an assignment test but doesn't need it
2009-12-31 13:44:03 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
" B & operator=(const B &); \n "
" }; \n "
" }; \n "
2010-01-03 08:26:02 +01:00
" A::B & A::B::operator=(const A::B &b) { return *this; } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// this test needs an assignment test and has it
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
" char * s; \n "
" B & operator=(const B &); \n "
" }; \n "
" }; \n "
" A::B & A::B::operator=(const A::B &b) \n "
" { \n "
" if (&b != this) \n "
" { \n "
" free(s); \n "
" s = strdup(b.s); \n "
" } \n "
" return *this; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// this test needs an assignment test but doesn't have it
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B \n "
" { \n "
" public: \n "
" char * s; \n "
" B & operator=(const B &); \n "
" }; \n "
" }; \n "
" A::B & A::B::operator=(const A::B &b) \n "
" { \n "
" free(s); \n "
" s = strdup(b.s); \n "
" return *this; \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:11]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. \n " , errout . str ( ) ) ;
2010-01-03 08:26:02 +01:00
}
2011-10-13 20:53:06 +02:00
void operatorEqToSelf3 ( ) {
2010-01-03 08:26:02 +01:00
// this test has multiple inheritance so there is no trivial way to test for self assignment but doesn't need it
checkOpertorEqToSelf (
" class A : public B, public C \n "
" { \n "
" public: \n "
" A & operator=(const A &a) { return *this; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// this test has multiple inheritance and needs an assignment test but there is no trivial way to test for it
checkOpertorEqToSelf (
" class A : public B, public C \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" return *this; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// this test has multiple inheritance so there is no trivial way to test for self assignment but doesn't need it
checkOpertorEqToSelf (
" class A : public B, public C \n "
" { \n "
" public: \n "
" A & operator=(const A &); \n "
" }; \n "
" A & A::operator=(const A &a) { return *this; } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// this test has multiple inheritance and needs an assignment test but there is no trivial way to test for it
checkOpertorEqToSelf (
" class A : public B, public C \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &); \n "
" }; \n "
" A & A::operator=(const A &a) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" return *this; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void operatorEqToSelf4 ( ) {
2010-01-03 08:26:02 +01:00
// this test has multiple inheritance so there is no trivial way to test for self assignment but doesn't need it
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B : public C, public D \n "
" { \n "
" public: \n "
" B & operator=(const B &b) { return *this; } \n "
" }; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// this test has multiple inheritance and needs an assignment test but there is no trivial way to test for it
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B : public C, public D \n "
" { \n "
" public: \n "
" char * s; \n "
" B & operator=(const B &b) \n "
" { \n "
" free(s); \n "
" s = strdup(b.s); \n "
" return *this; \n "
" } \n "
" }; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// this test has multiple inheritance so there is no trivial way to test for self assignment but doesn't need it
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B : public C, public D \n "
" { \n "
" public: \n "
" B & operator=(const B &); \n "
" }; \n "
" }; \n "
" A::B & A::B::operator=(const A::B &b) { return *this; } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// this test has multiple inheritance and needs an assignment test but there is no trivial way to test for it
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" class B : public C, public D \n "
" { \n "
" public: \n "
" char * s; \n "
" B & operator=(const B &); \n "
" }; \n "
" }; \n "
" A::B & A::B::operator=(const A::B &b) \n "
" { \n "
" free(s); \n "
" s = strdup(b.s); \n "
" return *this; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-31 13:44:03 +01:00
}
2011-10-13 20:53:06 +02:00
void operatorEqToSelf5 ( ) {
2010-01-08 19:15:24 +01:00
// ticket # 1233
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a) \n "
" { \n "
" if((&a!=this)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-06 18:26:29 +02:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a) \n "
" { \n "
" if((this!=&a)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-08 19:15:24 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a) \n "
" { \n "
" if(!(&a==this)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-06 18:26:29 +02:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a) \n "
" { \n "
" if(!(this==&a)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-08 19:15:24 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a) \n "
" { \n "
" if(false==(&a==this)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-06 18:26:29 +02:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a) \n "
" { \n "
" if(false==(this==&a)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-08 19:15:24 +01:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a) \n "
" { \n "
" if(true!=(&a==this)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-06 18:26:29 +02:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a) \n "
" { \n "
" if(true!=(this==&a)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a); \n "
" }; \n "
" A & A::operator=(const A &a) \n "
" { \n "
" if((&a!=this)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a); \n "
" }; \n "
" A & A::operator=(const A &a) \n "
" { \n "
" if((this!=&a)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a); \n "
" }; \n "
" A & A::operator=(const A &a) \n "
" { \n "
" if(!(&a==this)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a); \n "
" }; \n "
" A & A::operator=(const A &a) \n "
" { \n "
" if(!(this==&a)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a); \n "
" }; \n "
" A & A::operator=(const A &a) \n "
" { \n "
" if(false==(&a==this)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a); \n "
" }; \n "
" A & A::operator=(const A &a) \n "
" { \n "
" if(false==(this==&a)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a); \n "
" }; \n "
" A & A::operator=(const A &a) \n "
" { \n "
" if(true!=(&a==this)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" char *s; \n "
" A & operator=(const A &a); \n "
" }; \n "
" A & A::operator=(const A &a) \n "
" { \n "
" if(true!=(this==&a)) \n "
" { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" } \n "
" return *this; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-04-25 20:25:51 +02:00
checkOpertorEqToSelf (
" struct A { \n "
" char *s; \n "
" A& operator=(const B &b); \n "
" }; \n "
" A& A::operator=(const B &b) { \n "
" free(s); \n "
" s = strdup(a.s); \n "
" return *this; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-08 19:15:24 +01:00
}
2011-10-13 20:53:06 +02:00
void operatorEqToSelf6 ( ) {
2010-03-31 17:09:59 +02:00
// ticket # 1550
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" A & operator=(const A &a) \n "
" { \n "
" delete [] data; \n "
" data = new char[strlen(a.data) + 1]; \n "
" strcpy(data, a.data); \n "
" return *this; \n "
" } \n "
" private: \n "
" char * data; \n "
" }; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. \n " , errout . str ( ) ) ;
2010-04-06 18:26:29 +02:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" A & operator=(const A &a); \n "
" private: \n "
" char * data; \n "
" }; \n "
" A & A::operator=(const A &a) \n "
" { \n "
" delete [] data; \n "
" data = new char[strlen(a.data) + 1]; \n "
" strcpy(data, a.data); \n "
" return *this; \n "
" }; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. \n " , errout . str ( ) ) ;
2010-04-06 18:26:29 +02:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" A & operator=(const A &a) \n "
" { \n "
" delete data; \n "
" data = new char; \n "
" *data = *a.data; \n "
" return *this; \n "
" } \n "
" private: \n "
" char * data; \n "
" }; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. \n " , errout . str ( ) ) ;
2010-04-06 18:26:29 +02:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" A & operator=(const A &a); \n "
" private: \n "
" char * data; \n "
" }; \n "
" A & A::operator=(const A &a) \n "
" { \n "
" delete data; \n "
" data = new char; \n "
" *data = *a.data; \n "
" return *this; \n "
" }; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. \n " , errout . str ( ) ) ;
2010-03-31 17:09:59 +02:00
}
2011-10-13 20:53:06 +02:00
void operatorEqToSelf7 ( ) {
2010-09-11 08:23:30 +02:00
checkOpertorEqToSelf (
" class A \n "
" { \n "
" public: \n "
" A & assign(const A & a) \n "
" { \n "
" return *this; \n "
" } \n "
" A & operator=(const A &a) \n "
" { \n "
" return assign(a); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void operatorEqToSelf8 ( ) {
2010-11-09 06:58:19 +01:00
checkOpertorEqToSelf (
" class FMat \n "
" { \n "
" public: \n "
" FMat& copy(const FMat& rhs); \n "
" FMat& operator=(const FMat& in); \n "
" }; \n "
" FMat& FMat::copy(const FMat& rhs) \n "
" { \n "
" return *this; \n "
" } \n "
" FMat& FMat::operator=(const FMat& in) \n "
" { \n "
" return copy(in); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void operatorEqToSelf9 ( ) {
2011-02-20 02:02:16 +01:00
checkOpertorEqToSelf (
" class Foo \n "
" { \n "
" public: \n "
" Foo& operator=(Foo* pOther); \n "
" Foo& operator=(Foo& other); \n "
" }; \n "
" Foo& Foo::operator=(Foo* pOther) \n "
" { \n "
" return *this; \n "
" } \n "
" Foo& Foo::operator=(Foo& other) \n "
" { \n "
" return Foo::operator=(&other); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2008-12-18 22:28:57 +01:00
// Check that base classes have virtual destructors
2011-10-13 20:53:06 +02:00
void checkVirtualDestructor ( const char code [ ] ) {
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
2008-12-18 22:28:57 +01:00
// Tokenize..
2010-12-01 18:00:55 +01:00
Tokenizer tokenizer ( & settings , this ) ;
2008-12-18 22:28:57 +01:00
std : : istringstream istr ( code ) ;
2009-01-05 16:49:57 +01:00
tokenizer . tokenize ( istr , " test.cpp " ) ;
2008-12-18 22:28:57 +01:00
tokenizer . simplifyTokenList ( ) ;
// Check..
2009-03-20 17:30:24 +01:00
CheckClass checkClass ( & tokenizer , & settings , this ) ;
2008-12-18 22:28:57 +01:00
checkClass . virtualDestructor ( ) ;
}
2011-10-13 20:53:06 +02:00
void virtualDestructor1 ( ) {
2009-01-05 16:49:57 +01:00
// Base class not found
2008-12-18 22:28:57 +01:00
2011-04-20 18:03:16 +02:00
checkVirtualDestructor ( " class Derived : public Base { }; \n "
" Base *base = new Derived; \n "
" delete base; " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
2011-04-20 18:03:16 +02:00
checkVirtualDestructor ( " class Derived : Base { }; \n "
" Base *base = new Derived; \n "
" delete base; " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2011-10-13 20:53:06 +02:00
void virtualDestructor2 ( ) {
2009-01-05 16:49:57 +01:00
// Base class doesn't have a destructor
2008-12-18 22:28:57 +01:00
checkVirtualDestructor ( " class Base { }; \n "
2011-04-20 18:03:16 +02:00
" class Derived : public Base { public: ~Derived() { (void)11; } }; "
" Base *base = new Derived; \n "
" delete base; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. \n " , errout . str ( ) ) ;
2010-08-09 21:22:46 +02:00
checkVirtualDestructor ( " class Base { }; \n "
2011-04-20 18:03:16 +02:00
" class Derived : protected Base { public: ~Derived() { (void)11; } }; "
" Base *base = new Derived; \n "
" delete base; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. \n " , errout . str ( ) ) ;
2010-08-09 21:22:46 +02:00
checkVirtualDestructor ( " class Base { }; \n "
2011-04-20 18:03:16 +02:00
" class Derived : private Base { public: ~Derived() { (void)11; } }; "
" Base *base = new Derived; \n "
" delete base; " ) ;
2010-05-29 11:19:28 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
checkVirtualDestructor ( " class Base { }; \n "
2011-04-20 18:03:16 +02:00
" class Derived : Base { public: ~Derived() { (void)11; } }; "
" Base *base = new Derived; \n "
" delete base; " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2011-10-13 20:53:06 +02:00
void virtualDestructor3 ( ) {
2009-01-05 16:49:57 +01:00
// Base class has a destructor, but it's not virtual
2008-12-18 22:28:57 +01:00
checkVirtualDestructor ( " class Base { public: ~Base(); }; \n "
2011-04-20 18:03:16 +02:00
" class Derived : public Base { public: ~Derived() { (void)11; } }; "
" Base *base = new Derived; \n "
" delete base; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. \n " , errout . str ( ) ) ;
2010-08-09 21:22:46 +02:00
checkVirtualDestructor ( " class Base { public: ~Base(); }; \n "
2011-04-20 18:03:16 +02:00
" class Derived : protected Base { public: ~Derived() { (void)11; } }; "
" Base *base = new Derived; \n "
" delete base; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
checkVirtualDestructor ( " class Base { public: ~Base(); }; \n "
2011-04-20 18:03:16 +02:00
" class Derived : private Fred, public Base { public: ~Derived() { (void)11; } }; "
" Base *base = new Derived; \n "
" delete base; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2011-10-13 20:53:06 +02:00
void virtualDestructor4 ( ) {
2009-01-05 16:49:57 +01:00
// Derived class doesn't have a destructor => no error
2008-12-18 22:28:57 +01:00
checkVirtualDestructor ( " class Base { public: ~Base(); }; \n "
2011-04-20 18:03:16 +02:00
" class Derived : public Base { }; "
" Base *base = new Derived; \n "
" delete base; " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
checkVirtualDestructor ( " class Base { public: ~Base(); }; \n "
2011-04-20 18:03:16 +02:00
" class Derived : private Fred, public Base { }; "
" Base *base = new Derived; \n "
" delete base; " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2008-12-19 21:30:33 +01:00
2011-10-13 20:53:06 +02:00
void virtualDestructor5 ( ) {
2009-01-05 16:49:57 +01:00
// Derived class has empty destructor => no error
2008-12-19 21:30:33 +01:00
checkVirtualDestructor ( " class Base { public: ~Base(); }; \n "
2011-04-20 18:03:16 +02:00
" class Derived : public Base { public: ~Derived() {} }; "
" Base *base = new Derived; \n "
" delete base; " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-19 21:30:33 +01:00
checkVirtualDestructor ( " class Base { public: ~Base(); }; \n "
2011-04-20 18:03:16 +02:00
" class Derived : public Base { public: ~Derived(); }; Derived::~Derived() {} "
" Base *base = new Derived; \n "
" delete base; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void virtualDestructor6 ( ) {
2011-04-20 18:03:16 +02:00
// Only report error if base class pointer is deleted that
// points at derived class
checkVirtualDestructor ( " class Base { public: ~Base(); }; \n "
" class Derived : public Base { public: ~Derived() { (void)11; } }; " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-19 21:30:33 +01:00
}
2009-01-14 20:34:10 +01:00
2011-10-13 20:53:06 +02:00
void virtualDestructorProtected ( ) {
2009-05-06 22:22:26 +02:00
// Base class has protected destructor, it makes Base *p = new Derived(); fail
// during compilation time, so error is not possible. => no error
checkVirtualDestructor ( " class A \n "
" { \n "
" protected: \n "
" ~A() { } \n "
" }; \n "
" \n "
" class B : public A \n "
" { \n "
" public: \n "
" ~B() { int a; } \n "
" }; \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-05-06 22:22:26 +02:00
}
2009-01-14 20:34:10 +01:00
2011-10-13 20:53:06 +02:00
void virtualDestructorInherited ( ) {
2009-08-04 21:23:22 +02:00
// class A inherits virtual destructor from class Base -> no error
checkVirtualDestructor ( " class Base \n "
" { \n "
" public: \n "
" virtual ~Base() {} \n "
" }; \n "
" class A : private Base \n "
" { \n "
" public: \n "
" ~A() { } \n "
" }; \n "
" \n "
" class B : public A \n "
" { \n "
" public: \n "
" ~B() { int a; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// class A inherits virtual destructor from struct Base -> no error
// also notice that public is not given, but destructor is public, because
// we are using struct instead of class
checkVirtualDestructor ( " struct Base \n "
" { \n "
" virtual ~Base() {} \n "
" }; \n "
" class A : public Base \n "
" { \n "
" }; \n "
" \n "
" class B : public A \n "
" { \n "
" public: \n "
" ~B() { int a; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// Unknown Base class -> it could have virtual destructor, so ignore
checkVirtualDestructor ( " class A : private Base \n "
" { \n "
" public: \n "
" ~A() { } \n "
" }; \n "
" \n "
" class B : public A \n "
" { \n "
" public: \n "
" ~B() { int a; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// Virtual destructor is inherited -> no error
checkVirtualDestructor ( " class Base2 \n "
" { \n "
" virtual ~Base2() {} \n "
" }; \n "
" class Base : public Base2 \n "
" { \n "
" }; \n "
" class A : private Base \n "
" { \n "
" public: \n "
" ~A() { } \n "
" }; \n "
" \n "
" class B : public A \n "
" { \n "
" public: \n "
" ~B() { int a; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// class A doesn't inherit virtual destructor from class Base -> error
checkVirtualDestructor ( " class Base \n "
" { \n "
" public: \n "
2011-12-23 22:31:48 +01:00
" ~Base() {} \n "
2009-08-04 21:23:22 +02:00
" }; \n "
" class A : private Base \n "
" { \n "
" public: \n "
" ~A() { } \n "
" }; \n "
" \n "
" class B : public A \n "
" { \n "
" public: \n "
" ~B() { int a; } \n "
" }; \n " ) ;
2012-07-09 11:11:05 +02:00
TODO_ASSERT_EQUALS ( " [test.cpp:7]: (error) Class 'Base' which is inherited by class 'B' does not have a virtual destructor. \n " ,
2011-01-30 12:54:19 +01:00
" " , errout . str ( ) ) ;
2009-08-04 21:23:22 +02:00
}
2011-10-13 20:53:06 +02:00
void virtualDestructorTemplate ( ) {
2009-08-10 16:58:13 +02:00
checkVirtualDestructor ( " template <typename T> class A \n "
" { \n "
" public: \n "
" virtual ~A(){} \n "
" }; \n "
" template <typename T> class AA \n "
" { \n "
" public: \n "
" ~AA(){} \n "
" }; \n "
" class B : public A<int>, public AA<double> \n "
" { \n "
" public: \n "
" ~B(){int a;} \n "
2011-04-20 18:03:16 +02:00
" }; \n "
" \n "
" AA<double> *p = new B; delete p; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:9]: (error) Class 'AA<double>' which is inherited by class 'B' does not have a virtual destructor. \n " , errout . str ( ) ) ;
2009-08-10 16:58:13 +02:00
}
2011-10-13 20:53:06 +02:00
void checkNoConstructor ( const char code [ ] ) {
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
2011-08-07 09:28:08 +02:00
settings . addEnabled ( " style " ) ;
2010-12-01 18:00:55 +01:00
2009-02-21 14:35:55 +01:00
// Tokenize..
2010-12-01 18:00:55 +01:00
Tokenizer tokenizer ( & settings , this ) ;
2009-02-21 14:35:55 +01:00
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
tokenizer . simplifyTokenList ( ) ;
// Check..
2009-03-20 17:30:24 +01:00
CheckClass checkClass ( & tokenizer , & settings , this ) ;
2009-02-21 14:35:55 +01:00
checkClass . constructors ( ) ;
}
2011-10-13 20:53:06 +02:00
void noConstructor1 ( ) {
2009-02-21 14:35:55 +01:00
// There are nonstatic member variables - constructor is needed
checkNoConstructor ( " class Fred \n "
" { \n "
" int i; \n "
" }; \n " ) ;
2010-11-27 09:17:03 +01:00
ASSERT_EQUALS ( " [test.cpp:1]: (style) The class 'Fred' does not have a constructor. \n " , errout . str ( ) ) ;
2009-02-21 14:35:55 +01:00
}
2011-10-13 20:53:06 +02:00
void noConstructor2 ( ) {
2009-02-21 14:35:55 +01:00
checkNoConstructor ( " class Fred \n "
" { \n "
" public: \n "
" static void foobar(); \n "
" }; \n "
" \n "
" void Fred::foobar() \n "
" { } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void noConstructor3 ( ) {
2009-02-21 14:35:55 +01:00
checkNoConstructor ( " class Fred \n "
" { \n "
2009-12-19 17:58:52 +01:00
" private: \n "
2009-02-21 14:35:55 +01:00
" static int foobar; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void noConstructor4 ( ) {
2009-12-19 17:58:52 +01:00
checkNoConstructor ( " class Fred \n "
" { \n "
" public: \n "
" int foobar; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void noConstructor5 ( ) {
2010-08-09 17:50:26 +02:00
checkNoConstructor ( " namespace Foo \n "
" { \n "
" int i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void checkNoMemset ( const char code [ ] ) {
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
2009-09-02 22:32:15 +02:00
// Tokenize..
2010-12-01 18:00:55 +01:00
Tokenizer tokenizer ( & settings , this ) ;
2009-09-02 22:32:15 +02:00
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
// Check..
CheckClass checkClass ( & tokenizer , & settings , this ) ;
checkClass . noMemset ( ) ;
}
2011-10-13 20:53:06 +02:00
void memsetOnClass ( ) {
2011-02-25 01:59:50 +01:00
checkNoMemset ( " class Fred \n "
" { \n "
" }; \n "
" void f() \n "
" { \n "
" Fred fred; \n "
" memset(&fred, 0, sizeof(Fred)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-03-23 03:45:19 +01:00
checkNoMemset ( " class Fred \n "
" { \n "
" static std::string b; \n "
" }; \n "
" void f() \n "
" { \n "
" Fred fred; \n "
" memset(&fred, 0, sizeof(Fred)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkNoMemset ( " class Fred \n "
" { \n "
" std::string * b; \n "
" }; \n "
" void f() \n "
" { \n "
" Fred fred; \n "
" memset(&fred, 0, sizeof(Fred)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-02-25 01:59:50 +01:00
checkNoMemset ( " class Fred \n "
" { \n "
" std::string b; \n "
" }; \n "
" void f() \n "
" { \n "
" Fred fred; \n "
" memset(&fred, 0, sizeof(Fred)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (error) Using 'memset' on class that contains a 'std::string'. \n " , errout . str ( ) ) ;
2011-02-25 01:59:50 +01:00
2011-03-23 03:45:19 +01:00
checkNoMemset ( " class Fred \n "
" { \n "
" mutable std::string b; \n "
" }; \n "
" void f() \n "
" { \n "
" Fred fred; \n "
" memset(&fred, 0, sizeof(Fred)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (error) Using 'memset' on class that contains a 'std::string'. \n " , errout . str ( ) ) ;
2011-03-23 03:45:19 +01:00
2011-02-25 01:59:50 +01:00
checkNoMemset ( " class Fred \n "
" { \n "
" }; \n "
" void f() \n "
" { \n "
" Fred fred; \n "
" memset(&fred, 0, sizeof(fred)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkNoMemset ( " class Fred \n "
" { \n "
" std::string s; \n "
" }; \n "
" void f() \n "
" { \n "
" Fred fred; \n "
" memset(&fred, 0, sizeof(fred)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (error) Using 'memset' on class that contains a 'std::string'. \n " , errout . str ( ) ) ;
2011-03-09 09:29:30 +01:00
checkNoMemset ( " class Fred \n "
" { \n "
" std::string s; \n "
" }; \n "
" class Pebbles: public Fred {}; \n "
" void f() \n "
" { \n "
" Pebbles pebbles; \n "
" memset(&pebbles, 0, sizeof(pebbles)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:9]: (error) Using 'memset' on class that contains a 'std::string'. \n " , errout . str ( ) ) ;
2011-03-09 10:10:39 +01:00
checkNoMemset ( " class Fred \n "
" { \n "
" virtual ~Fred(); \n "
" }; \n "
" void f() \n "
" { \n "
" Fred fred; \n "
" memset(&fred, 0, sizeof(fred)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (error) Using 'memset' on class that contains a virtual method. \n " , errout . str ( ) ) ;
2011-03-09 10:10:39 +01:00
2011-04-22 15:12:08 +02:00
checkNoMemset ( " class Fred \n "
" { \n "
" virtual ~Fred(); \n "
" }; \n "
" void f() \n "
" { \n "
" static Fred fred; \n "
" memset(&fred, 0, sizeof(fred)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (error) Using 'memset' on class that contains a virtual method. \n " , errout . str ( ) ) ;
2011-04-22 15:12:08 +02:00
2011-03-09 10:10:39 +01:00
checkNoMemset ( " class Fred \n "
" { \n "
" }; \n "
" class Wilma \n "
" { \n "
" virtual ~Wilma(); \n "
" }; \n "
" class Pebbles: public Fred, Wilma {}; \n "
" void f() \n "
" { \n "
" Pebbles pebbles; \n "
" memset(&pebbles, 0, sizeof(pebbles)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:12]: (error) Using 'memset' on class that contains a virtual method. \n " , errout . str ( ) ) ;
2011-03-13 04:41:21 +01:00
// Fred not defined in scope
checkNoMemset ( " namespace n1 { \n "
" class Fred \n "
" { \n "
" std::string b; \n "
" }; \n "
" } \n "
" void f() \n "
" { \n "
" Fred fred; \n "
" memset(&fred, 0, sizeof(Fred)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// Fred with namespace qualifier
checkNoMemset ( " namespace n1 { \n "
" class Fred \n "
" { \n "
" std::string b; \n "
" }; \n "
" } \n "
" void f() \n "
" { \n "
" n1::Fred fred; \n "
" memset(&fred, 0, sizeof(n1::Fred)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:10]: (error) Using 'memset' on class that contains a 'std::string'. \n " , errout . str ( ) ) ;
2011-03-13 04:41:21 +01:00
// Fred with namespace qualifier
checkNoMemset ( " namespace n1 { \n "
" class Fred \n "
" { \n "
" std::string b; \n "
" }; \n "
" } \n "
" void f() \n "
" { \n "
" n1::Fred fred; \n "
" memset(&fred, 0, sizeof(fred)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:10]: (error) Using 'memset' on class that contains a 'std::string'. \n " , errout . str ( ) ) ;
2011-02-25 01:59:50 +01:00
}
2011-10-13 20:53:06 +02:00
void memsetOnStruct ( ) {
2011-02-25 01:59:50 +01:00
checkNoMemset ( " struct A \n "
2009-09-02 22:32:15 +02:00
" { \n "
" }; \n "
" void f() \n "
" { \n "
2010-02-04 19:40:35 +01:00
" A a; \n "
" memset(&a, 0, sizeof(A)); \n "
2009-09-02 22:32:15 +02:00
" } \n " ) ;
2010-02-04 19:40:35 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-02 22:32:15 +02:00
checkNoMemset ( " struct A \n "
" { \n "
" }; \n "
" void f() \n "
" { \n "
2010-02-04 19:40:35 +01:00
" struct A a; \n "
2011-02-25 01:59:50 +01:00
" memset(&a, 0, sizeof(struct A)); \n "
2009-09-02 22:32:15 +02:00
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-02-25 01:59:50 +01:00
checkNoMemset ( " struct A \n "
2009-09-02 22:32:15 +02:00
" { \n "
" }; \n "
" void f() \n "
" { \n "
2011-02-25 01:59:50 +01:00
" struct A a; \n "
" memset(&a, 0, sizeof(A)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkNoMemset ( " void f() \n "
" { \n "
" struct sockaddr_in6 fail; \n "
" memset(&fail, 0, sizeof(struct sockaddr_in6)); \n "
2009-09-02 22:32:15 +02:00
" } \n " ) ;
2009-09-02 22:51:07 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-02 22:32:15 +02:00
checkNoMemset ( " struct A \n "
" { \n "
" void g( struct sockaddr_in6& a); \n "
" private: \n "
" std::string b; \n "
" }; \n "
" void f() \n "
" { \n "
" struct A fail; \n "
" memset(&fail, 0, sizeof(struct A)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:10]: (error) Using 'memset' on struct that contains a 'std::string'. \n " , errout . str ( ) ) ;
2011-02-16 21:31:35 +01:00
checkNoMemset ( " struct Fred \n "
" { \n "
" std::string s; \n "
" }; \n "
" void f() \n "
" { \n "
" Fred fred; \n "
" memset(&fred, 0, sizeof(fred)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (error) Using 'memset' on struct that contains a 'std::string'. \n " , errout . str ( ) ) ;
2011-03-24 02:58:58 +01:00
checkNoMemset ( " struct Stringy { \n "
" std::string inner; \n "
" }; \n "
" struct Foo { \n "
" Stringy s; \n "
2011-03-25 12:58:51 +01:00
" }; \n "
2011-03-24 02:58:58 +01:00
" int main() { \n "
" Foo foo; \n "
" memset(&foo, 0, sizeof(Foo)); \n "
" } \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:9]: (error) Using 'memset' on struct that contains a 'std::string'. \n " , errout . str ( ) ) ;
2009-09-02 22:32:15 +02:00
}
2009-09-12 15:25:02 +02:00
2011-10-13 20:53:06 +02:00
void memsetVector ( ) {
2011-02-25 01:59:50 +01:00
checkNoMemset ( " class A \n "
2011-03-25 12:58:51 +01:00
" { std::vector<int> ints; }; \n "
2011-02-25 01:59:50 +01:00
" \n "
" void f() \n "
" { \n "
" A a; \n "
" memset(&a, 0, sizeof(A)); \n "
" } " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (error) Using 'memset' on class that contains a 'std::vector'. \n " , errout . str ( ) ) ;
2011-02-25 01:59:50 +01:00
checkNoMemset ( " struct A \n "
2011-03-25 12:58:51 +01:00
" { std::vector<int> ints; }; \n "
2011-02-25 01:59:50 +01:00
" \n "
" void f() \n "
" { \n "
" A a; \n "
" memset(&a, 0, sizeof(A)); \n "
" } " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'. \n " , errout . str ( ) ) ;
2011-02-25 01:59:50 +01:00
checkNoMemset ( " struct A \n "
2011-03-25 12:58:51 +01:00
" { std::vector<int> ints; }; \n "
2011-02-25 01:59:50 +01:00
" \n "
" void f() \n "
" { \n "
" A a; \n "
" memset(&a, 0, sizeof(struct A)); \n "
" } " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'. \n " , errout . str ( ) ) ;
2011-02-25 01:59:50 +01:00
2010-02-04 19:40:35 +01:00
checkNoMemset ( " struct A \n "
2011-03-25 12:58:51 +01:00
" { std::vector<int> ints; }; \n "
2010-02-04 19:40:35 +01:00
" \n "
" void f() \n "
" { \n "
" A a; \n "
2011-02-25 01:59:50 +01:00
" memset(&a, 0, sizeof(a)); \n "
" } " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'. \n " , errout . str ( ) ) ;
2011-02-25 01:59:50 +01:00
checkNoMemset ( " class A \n "
2011-03-25 12:58:51 +01:00
" { std::vector< std::vector<int> > ints; }; \n "
2011-02-25 01:59:50 +01:00
" \n "
" void f() \n "
" { \n "
" A a; \n "
" memset(&a, 0, sizeof(A)); \n "
" } " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (error) Using 'memset' on class that contains a 'std::vector'. \n " , errout . str ( ) ) ;
2011-02-25 01:59:50 +01:00
checkNoMemset ( " struct A \n "
2011-03-25 12:58:51 +01:00
" { std::vector< std::vector<int> > ints; }; \n "
2011-02-25 01:59:50 +01:00
" \n "
" void f() \n "
" { \n "
" A a; \n "
" memset(&a, 0, sizeof(A)); \n "
2010-02-04 19:40:35 +01:00
" } " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'. \n " , errout . str ( ) ) ;
2010-02-04 21:49:58 +01:00
checkNoMemset ( " struct A \n "
2011-03-25 12:58:51 +01:00
" { std::vector< std::vector<int> > ints; }; \n "
2010-02-04 21:49:58 +01:00
" \n "
" void f() \n "
" { \n "
" A a; \n "
2011-02-25 01:59:50 +01:00
" memset(&a, 0, sizeof(a)); \n "
2010-02-04 21:49:58 +01:00
" } " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'. \n " , errout . str ( ) ) ;
2010-02-04 20:53:04 +01:00
checkNoMemset ( " struct A \n "
2011-03-25 12:58:51 +01:00
" { std::vector<int *> ints; }; \n "
2010-02-04 20:53:04 +01:00
" \n "
" void f() \n "
" { \n "
" A a; \n "
2011-02-25 01:59:50 +01:00
" memset(&a, 0, sizeof(A)); \n "
2010-02-04 20:53:04 +01:00
" } " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'. \n " , errout . str ( ) ) ;
2010-02-04 19:40:35 +01:00
}
2009-09-12 15:25:02 +02:00
2011-10-13 20:53:06 +02:00
void checkThisSubtraction ( const char code [ ] ) {
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
2011-08-07 09:28:08 +02:00
settings . addEnabled ( " style " ) ;
2010-12-01 18:00:55 +01:00
2009-09-12 15:25:02 +02:00
// Tokenize..
2010-12-01 18:00:55 +01:00
Tokenizer tokenizer ( & settings , this ) ;
2009-09-12 15:25:02 +02:00
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
tokenizer . simplifyTokenList ( ) ;
// Check..
CheckClass checkClass ( & tokenizer , & settings , this ) ;
checkClass . thisSubtraction ( ) ;
}
2011-10-13 20:53:06 +02:00
void this_subtraction ( ) {
2009-09-12 15:25:02 +02:00
checkThisSubtraction ( " ; this-x ; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (warning) Suspicious pointer subtraction. Did you intend to write '->'? \n " , errout . str ( ) ) ;
2009-11-04 20:36:27 +01:00
checkThisSubtraction ( " ; *this = *this-x ; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkThisSubtraction ( " ; *this = *this-x ; \n "
" this-x ; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Suspicious pointer subtraction. Did you intend to write '->'? \n " , errout . str ( ) ) ;
2009-11-04 20:36:27 +01:00
2009-11-04 20:38:40 +01:00
checkThisSubtraction ( " ; *this = *this-x ; \n "
" this-x ; \n "
" this-x ; \n " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Suspicious pointer subtraction. Did you intend to write '->'? \n "
" [test.cpp:3]: (warning) Suspicious pointer subtraction. Did you intend to write '->'? \n " , errout . str ( ) ) ;
2009-09-12 15:25:02 +02:00
}
2010-01-23 09:19:22 +01:00
2011-12-15 20:18:52 +01:00
void checkConst ( const char code [ ] , const Settings * s = 0 , bool inconclusive = true ) {
2010-01-23 09:19:22 +01:00
// Clear the error log
errout . str ( " " ) ;
// Check..
Settings settings ;
2010-08-07 13:08:36 +02:00
if ( s )
settings = * s ;
else
2011-10-30 11:21:46 +01:00
settings . addEnabled ( " style " ) ;
2011-12-15 20:18:52 +01:00
settings . inconclusive = inconclusive ;
2010-12-01 18:00:55 +01:00
// Tokenize..
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
tokenizer . simplifyTokenList ( ) ;
2010-01-23 09:19:22 +01:00
CheckClass checkClass ( & tokenizer , & settings , this ) ;
checkClass . checkConst ( ) ;
}
2011-10-13 20:53:06 +02:00
void const1 ( ) {
2010-01-23 09:19:22 +01:00
checkConst ( " class Fred { \n "
" int a; \n "
" int getA() { return a; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::getA' can be const. \n " , errout . str ( ) ) ;
2010-01-23 20:47:29 +01:00
2010-01-29 19:38:56 +01:00
checkConst ( " class Fred { \n "
" const std::string foo() { return " " ; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static. \n " , errout . str ( ) ) ;
2010-01-29 19:38:56 +01:00
checkConst ( " class Fred { \n "
" std::string s; \n "
" const std::string & foo() { return " " ; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static. \n " , errout . str ( ) ) ;
2010-01-29 19:38:56 +01:00
2010-01-23 20:47:29 +01:00
// constructors can't be const..
checkConst ( " class Fred { \n "
" int a; \n "
" public: \n "
" Fred() { } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-23 20:59:20 +01:00
// assignment through |=..
checkConst ( " class Fred { \n "
" int a; \n "
" int setA() { a |= true; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-04-18 18:51:38 +02:00
// functions with a call to a member function can only be const, if that member function is const, too.. (#1305)
checkConst ( " class foo { \n "
2010-01-23 21:08:40 +01:00
" public: \n "
" int x; \n "
2012-04-18 18:51:38 +02:00
" void a() { x = 1; } \n "
2010-01-23 21:08:40 +01:00
" void b() { a(); } \n "
2012-04-18 18:51:38 +02:00
" }; " ) ;
2010-01-23 21:08:40 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-24 18:26:39 +01:00
2012-04-18 18:51:38 +02:00
checkConst ( " class Fred { \n "
" public: \n "
" int x; \n "
" int a() const { return x; } \n "
" void b() { a(); } \n "
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (style, inconclusive) Technically the member function 'Fred::b' can be const. \n " , errout . str ( ) ) ;
2012-04-18 18:51:38 +02:00
2012-05-16 20:57:12 +02:00
checkConst ( " class Fred { \n "
" public: \n "
" int x; \n "
" void b() { a(); } \n "
" }; " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (performance, inconclusive) Technically the member function 'Fred::b' can be static. \n " , errout . str ( ) ) ;
2012-05-16 20:57:12 +02:00
2010-01-24 18:26:39 +01:00
// static functions can't be const..
checkConst ( " class foo \n "
" { \n "
" public: \n "
" static unsigned get() \n "
" { return 0; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-03-17 00:54:52 +01:00
checkConst ( " class Fred { \n "
" const std::string foo() const throw() { return " " ; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static. \n " , errout . str ( ) ) ;
2010-02-08 07:25:19 +01:00
}
2011-10-13 20:53:06 +02:00
void const2 ( ) {
2010-02-08 07:25:19 +01:00
// ticket 1344
// assignment to variable can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo() { s = " " ; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to function argument reference can be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a) { a = s; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. \n " , errout . str ( ) ) ;
2010-02-08 07:25:19 +01:00
// assignment to variable can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a) { s = a; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to function argument references can be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a, std::string & b) { a = s; b = s; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. \n " , errout . str ( ) ) ;
2010-02-08 07:25:19 +01:00
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a, std::string & b) { s = a; s = b; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a, std::string & b) { s = a; b = s; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a, std::string & b) { a = s; s = b; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const3 ( ) {
2010-02-08 07:25:19 +01:00
// assignment to function argument pointer can be const
checkConst ( " class Fred { \n "
" int s; \n "
" void foo(int * a) { *a = s; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. \n " , errout . str ( ) ) ;
2010-02-08 07:25:19 +01:00
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" int s; \n "
" void foo(int * a) { s = *a; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to function argument pointers can be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string * a, std::string * b) { *a = s; *b = s; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. \n " , errout . str ( ) ) ;
2010-02-08 07:25:19 +01:00
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string * a, std::string * b) { s = *a; s = *b; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string * a, std::string * b) { s = *a; *b = s; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string * a, std::string * b) { *a = s; s = b; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-23 09:19:22 +01:00
}
2010-01-23 22:36:04 +01:00
2011-10-13 20:53:06 +02:00
void const4 ( ) {
2010-03-05 17:06:25 +01:00
checkConst ( " class Fred { \n "
" int a; \n "
" int getA(); \n "
" }; \n "
" int Fred::getA() { return a; } " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::getA' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
checkConst ( " class Fred { \n "
" std::string s; \n "
" const std::string & foo(); \n "
" }; \n "
" const std::string & Fred::foo() { return " " ; } " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
2012-04-18 18:51:38 +02:00
// functions with a function call to a non-const member can't be const.. (#1305)
2010-07-26 16:46:37 +02:00
checkConst ( " class Fred \n "
2010-03-05 17:06:25 +01:00
" { \n "
" public: \n "
" int x; \n "
2012-04-18 18:51:38 +02:00
" void a() { x = 1; } \n "
2010-03-05 17:06:25 +01:00
" void b(); \n "
" }; \n "
" void Fred::b() { a(); } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// static functions can't be const..
2010-07-26 16:46:37 +02:00
checkConst ( " class Fred \n "
2010-03-05 17:06:25 +01:00
" { \n "
" public: \n "
" static unsigned get(); \n "
" }; \n "
" static unsigned Fred::get() { return 0; } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to variable can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
2010-07-26 16:46:37 +02:00
" void foo(); \n "
2010-03-05 17:06:25 +01:00
" }; \n "
" void Fred::foo() { s = " " ; } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to function argument reference can be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a); \n "
" }; \n "
" void Fred::foo(std::string & a) { a = s; } " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
// assignment to variable can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a); \n "
" }; \n "
" void Fred::foo(std::string & a) { s = a; } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to function argument references can be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a, std::string & b); \n "
" }; \n "
" void Fred::foo(std::string & a, std::string & b) { a = s; b = s; } " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a, std::string & b); \n "
" }; \n "
" void Fred::foo(std::string & a, std::string & b) { s = a; s = b; } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a, std::string & b); \n "
" }; \n "
" void Fred::foo(std::string & a, std::string & b) { s = a; b = s; } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string & a, std::string & b); \n "
" }; \n "
2010-07-26 16:46:37 +02:00
" void Fred::foo(std::string & a, std::string & b) { a = s; s = b; } " ) ;
2010-03-05 17:06:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to function argument pointer can be const
checkConst ( " class Fred { \n "
" int s; \n "
" void foo(int * a); \n "
" }; \n "
" void Fred::foo(int * a) { *a = s; } " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" int s; \n "
" void foo(int * a); \n "
" }; \n "
" void Fred::foo(int * a) { s = *a; } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to function argument pointers can be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string * a, std::string * b); \n "
" }; \n "
" void Fred::foo(std::string * a, std::string * b) { *a = s; *b = s; } " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string * a, std::string * b); \n "
" }; \n "
" void Fred::foo(std::string * a, std::string * b) { s = *a; s = *b; } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string * a, std::string * b); \n "
" }; \n "
" void Fred::foo(std::string * a, std::string * b) { s = *a; *b = s; } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment to variable, can't be const
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(std::string * a, std::string * b); \n "
" }; \n "
" void Fred::foo(std::string * a, std::string * b) { *a = s; s = b; } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// check functions with same name
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo(); \n "
" void foo(std::string & a); \n "
" void foo(const std::string & a); \n "
" }; \n "
" void Fred::foo() { } "
" void Fred::foo(std::string & a) { a = s; } "
" void Fred::foo(const std::string & a) { s = a; } " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:7] -> [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static. \n "
2012-05-06 19:37:41 +02:00
" [test.cpp:7] -> [test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
2010-12-15 18:45:53 +01:00
// check functions with different or missing parameter names
2010-03-05 17:06:25 +01:00
checkConst ( " class Fred { \n "
" std::string s; \n "
" void foo1(int, int); \n "
" void foo2(int a, int b); \n "
" void foo3(int, int b); \n "
" void foo4(int a, int); \n "
" void foo5(int a, int b); \n "
" }; \n "
" void Fred::foo1(int a, int b) { } \n "
" void Fred::foo2(int c, int d) { } \n "
" void Fred::foo3(int a, int b) { } \n "
" void Fred::foo4(int a, int b) { } \n "
" void Fred::foo5(int, int) { } " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:9] -> [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::foo1' can be static. \n "
" [test.cpp:10] -> [test.cpp:4]: (performance, inconclusive) Technically the member function 'Fred::foo2' can be static. \n "
" [test.cpp:11] -> [test.cpp:5]: (performance, inconclusive) Technically the member function 'Fred::foo3' can be static. \n "
" [test.cpp:12] -> [test.cpp:6]: (performance, inconclusive) Technically the member function 'Fred::foo4' can be static. \n "
" [test.cpp:13] -> [test.cpp:7]: (performance, inconclusive) Technically the member function 'Fred::foo5' can be static. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
// check nested classes
checkConst ( " class Fred { \n "
" class A { \n "
" int a; \n "
" int getA() { return a; } \n "
" }; \n "
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::A::getA' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
checkConst ( " class Fred { \n "
" class A { \n "
" int a; \n "
" int getA(); \n "
" }; \n "
" int A::getA() { return a; } \n "
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:6] -> [test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::A::getA' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
checkConst ( " class Fred { \n "
" class A { \n "
" int a; \n "
" int getA(); \n "
" }; \n "
" }; \n "
" int Fred::A::getA() { return a; } " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:7] -> [test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::A::getA' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
// check deeply nested classes
checkConst ( " class Fred { \n "
" class B { \n "
" int b; \n "
" int getB() { return b; } \n "
" class A { \n "
" int a; \n "
" int getA() { return a; } \n "
" }; \n "
" }; \n "
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::B::getB' can be const. \n "
" [test.cpp:7]: (style, inconclusive) Technically the member function 'Fred::B::A::getA' can be const. \n "
2010-11-02 18:28:55 +01:00
, errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
checkConst ( " class Fred { \n "
" class B { \n "
" int b; \n "
" int getB(); \n "
" class A { \n "
" int a; \n "
" int getA(); \n "
" }; \n "
" int A::getA() { return a; } \n "
" }; \n "
" int B::getB() { return b; } \n "
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::B::getB' can be const. \n "
" [test.cpp:9] -> [test.cpp:7]: (style, inconclusive) Technically the member function 'Fred::B::A::getA' can be const. \n " , errout . str ( ) ) ;
2010-11-02 18:28:55 +01:00
checkConst ( " class Fred { \n "
" class B { \n "
" int b; \n "
" int getB(); \n "
" class A { \n "
" int a; \n "
" int getA(); \n "
" }; \n "
" }; \n "
" int B::A::getA() { return a; } \n "
" int B::getB() { return b; } \n "
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::B::getB' can be const. \n "
" [test.cpp:10] -> [test.cpp:7]: (style, inconclusive) Technically the member function 'Fred::B::A::getA' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
checkConst ( " class Fred { \n "
" class B { \n "
" int b; \n "
" int getB(); \n "
" class A { \n "
" int a; \n "
" int getA(); \n "
" }; \n "
" }; \n "
" }; \n "
" int Fred::B::A::getA() { return a; } \n "
" int Fred::B::getB() { return b; } \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:12] -> [test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::B::getB' can be const. \n "
" [test.cpp:11] -> [test.cpp:7]: (style, inconclusive) Technically the member function 'Fred::B::A::getA' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
}
2010-01-23 22:36:04 +01:00
// operator< can often be const
2011-10-13 20:53:06 +02:00
void constoperator1 ( ) {
2010-01-23 22:36:04 +01:00
checkConst ( " struct Fred { \n "
" int a; \n "
" bool operator<(const Fred &f) { return (a < f.a); } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::operator<' can be const. \n " , errout . str ( ) ) ;
2010-01-23 22:36:04 +01:00
}
2010-01-24 13:33:30 +01:00
2010-04-02 22:03:07 +02:00
// operator<<
2011-10-13 20:53:06 +02:00
void constoperator2 ( ) {
2010-04-02 22:03:07 +02:00
checkConst ( " struct Foo { \n "
" void operator<<(int); \n "
" }; \n "
" struct Fred { \n "
" Foo foo; \n "
" void x() \n "
" { \n "
" foo << 123; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-04-18 18:51:38 +02:00
checkConst ( " struct Foo { \n "
" void operator<<(int); \n "
" }; \n "
" struct Fred { \n "
" Foo foo; \n "
" void x() \n "
" { \n "
" std::cout << foo << 123; \n "
" } \n "
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (style, inconclusive) Technically the member function 'Fred::x' can be const. \n " , errout . str ( ) ) ;
2010-04-02 22:03:07 +02:00
}
2011-10-13 20:53:06 +02:00
void constoperator3 ( ) {
2010-08-30 17:14:20 +02:00
checkConst ( " struct Fred { \n "
" int array[10]; \n "
" int const & operator [] (unsigned int index) const { return array[index]; } \n "
" int & operator [] (unsigned int index) { return array[index]; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " struct Fred { \n "
" int array[10]; \n "
" int const & operator [] (unsigned int index) { return array[index]; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::operator[]' can be const. \n " , errout . str ( ) ) ;
2010-08-30 17:14:20 +02:00
}
2011-10-13 20:53:06 +02:00
void constoperator4 ( ) {
2010-12-29 20:22:06 +01:00
checkConst ( " struct Fred { \n "
" int array[10]; \n "
" typedef int* (Fred::*UnspecifiedBoolType); \n "
" operator UnspecifiedBoolType() { }; \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::operatorint**' can be const. \n " , errout . str ( ) ) ;
2010-12-29 20:22:06 +01:00
checkConst ( " struct Fred { \n "
" int array[10]; \n "
" typedef int* (Fred::*UnspecifiedBoolType); \n "
" operator UnspecifiedBoolType() { array[0] = 0; }; \n "
" }; \n " ) ;
2011-01-01 17:54:37 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-29 20:22:06 +01:00
}
2012-03-24 13:48:33 +01:00
void constoperator5 ( ) { // ticket #3252
checkConst ( " class A { \n "
" int c; \n "
" public: \n "
" operator int& () {return c} \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class A { \n "
" int c; \n "
" public: \n "
" operator const int& () {return c} \n "
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::operatorconstint&' can be const. \n " , errout . str ( ) ) ;
2012-03-24 13:48:33 +01:00
checkConst ( " class A { \n "
" int c; \n "
" public: \n "
" operator int () {return c} \n "
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::operatorint' can be const. \n " , errout . str ( ) ) ;
2012-03-24 13:48:33 +01:00
}
2011-10-13 20:53:06 +02:00
void const5 ( ) {
2010-03-12 18:30:20 +01:00
// ticket #1482
checkConst ( " class A { \n "
" int a; \n "
" bool foo(int i) \n "
" { \n "
" bool same; \n "
" same = (i == a); \n "
" return same; \n "
" } \n "
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'A::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-12 18:30:20 +01:00
}
2011-10-13 20:53:06 +02:00
void const6 ( ) {
2012-08-01 19:24:38 +02:00
// ticket #1491
2010-03-13 08:06:20 +01:00
checkConst ( " class foo { \n "
" public: \n "
" }; \n "
" void bar() {} " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-03-19 17:40:23 +01:00
checkConst ( " class Fred \n "
" { \n "
" public: \n "
" void foo() { } \n "
" }; " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static. \n " , errout . str ( ) ) ;
2010-03-19 19:04:56 +01:00
checkConst ( " struct fast_string \n "
" { \n "
" union \n "
" { \n "
" char buff[100]; \n "
" }; \n "
" void set_type(char t); \n "
" }; \n "
" inline void fast_string::set_type(char t) \n "
" { \n "
" buff[10] = t; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-03-13 08:06:20 +01:00
}
2011-10-13 20:53:06 +02:00
void const7 ( ) {
2010-03-16 07:31:40 +01:00
checkConst ( " class foo { \n "
" int a; \n "
" public: \n "
" void set(int i) { a = i; } \n "
" void set(const foo & f) { *this = f; } \n "
" }; \n "
" void bar() {} " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const8 ( ) {
2010-03-23 07:34:34 +01:00
// ticket #1517
checkConst ( " class A { \n "
" public: \n "
" A():m_strValue( " " ){} \n "
" std::string strGetString() { return m_strValue; } \n "
" private: \n "
" std::string m_strValue; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::strGetString' can be const. \n " , errout . str ( ) ) ;
2010-03-23 07:34:34 +01:00
}
2011-10-13 20:53:06 +02:00
void const9 ( ) {
2010-03-23 07:37:20 +01:00
// ticket #1515
checkConst ( " class wxThreadInternal { \n "
" public: \n "
" void SetExitCode(wxThread::ExitCode exitcode) { m_exitcode = exitcode; } \n "
" private: \n "
" wxThread::ExitCode m_exitcode; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-23 07:37:20 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const10 ( ) {
2010-03-26 16:30:30 +01:00
// ticket #1522
2010-03-24 19:31:30 +01:00
checkConst ( " class A { \n "
" public: \n "
" int foo() { return x = 0; } \n "
" private: \n "
" int x; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-24 19:31:30 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-03-26 16:30:30 +01:00
checkConst ( " class A { \n "
" public: \n "
" int foo() { return (x ? x : x = 0); } \n "
" private: \n "
" int x; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-26 16:30:30 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class A { \n "
" public: \n "
" int foo() { return (x ? x = 0 : x); } \n "
" private: \n "
" int x; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-26 16:30:30 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-03-24 19:31:30 +01:00
}
2011-10-13 20:53:06 +02:00
void const11 ( ) {
2010-03-26 18:16:33 +01:00
// ticket #1529
checkConst ( " class A { \n "
" public: \n "
" void set(struct tm time) { m_time = time; } \n "
" private: \n "
" struct tm m_time; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-26 18:16:33 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const12 ( ) {
2010-03-26 19:06:00 +01:00
// ticket #1525
checkConst ( " class A { \n "
" public: \n "
" int foo() { x = 0; } \n "
" private: \n "
" mutable int x; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'A::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-26 19:06:00 +01:00
}
2011-10-13 20:53:06 +02:00
void const13 ( ) {
2010-03-26 20:14:31 +01:00
// ticket #1519
checkConst ( " class A { \n "
" public: \n "
" A(){} \n "
" std::vector<int> GetVec() {return m_vec;} \n "
" std::pair<int,double> GetPair() {return m_pair;} \n "
" private: \n "
" std::vector<int> m_vec; \n "
" std::pair<int,double> m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetVec' can be const. \n "
" [test.cpp:5]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-26 20:14:31 +01:00
checkConst ( " class A { \n "
" public: \n "
" A(){} \n "
" const std::vector<int> & GetVec() {return m_vec;} \n "
" const std::pair<int,double> & GetPair() {return m_pair;} \n "
" private: \n "
" std::vector<int> m_vec; \n "
" std::pair<int,double> m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetVec' can be const. \n "
" [test.cpp:5]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-26 20:14:31 +01:00
}
2011-10-13 20:53:06 +02:00
void const14 ( ) {
2010-03-27 20:41:17 +01:00
// extends ticket 1519
2010-03-27 14:11:46 +01:00
checkConst ( " class A { \n "
" public: \n "
" A(){} \n "
" std::pair<std::vector<int>,double> GetPair() {return m_pair;} \n "
" private: \n "
" std::pair<std::vector<int>,double> m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " class A { \n "
" public: \n "
" A(){} \n "
" const std::pair<std::vector<int>,double>& GetPair() {return m_pair;} \n "
" private: \n "
" std::pair<std::vector<int>,double> m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " class A { \n "
" public: \n "
" A(){} \n "
" std::pair<std::vector<int>,double>& GetPair() {return m_pair;} \n "
" private: \n "
" std::pair<std::vector<int>,double> m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair<int ,double> GetPair() {return m_pair;} \n "
" private: \n "
" pair<int ,double> m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" const pair<int ,double> & GetPair() {return m_pair;} \n "
" private: \n "
" pair<int ,double> m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair<int ,double> & GetPair() {return m_pair;} \n "
" private: \n "
" pair<int ,double> m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class A { \n "
" public: \n "
" A(){} \n "
" std::pair< int,std::vector<int> > GetPair() {return m_pair;} \n "
" private: \n "
" std::pair< int,std::vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " class A { \n "
" public: \n "
" A(){} \n "
" const std::pair< int,std::vector<int> >& GetPair() {return m_pair;} \n "
" private: \n "
" std::pair< int,std::vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " class A { \n "
" public: \n "
" A(){} \n "
" std::pair< int,std::vector<int> >& GetPair() {return m_pair;} \n "
" private: \n "
" std::pair< int,std::vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair< int,vector<int> > GetPair() {return m_pair;} \n "
" private: \n "
" pair< int,vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" const pair< int,vector<int> >& GetPair() {return m_pair;} \n "
" private: \n "
" pair< int,vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair< int,vector<int> >& GetPair() {return m_pair;} \n "
" private: \n "
" pair< int,vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair< vector<int>, int > GetPair() {return m_pair;} \n "
" private: \n "
" pair< vector<int>, int > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" const pair< vector<int>, int >& GetPair() {return m_pair;} \n "
" private: \n "
" pair< vector<int>, int > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair< vector<int>, int >& GetPair() {return m_pair;} \n "
" private: \n "
" pair< vector<int>, int > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class A { \n "
" public: \n "
" A(){} \n "
" std::pair< std::vector<int>,std::vector<int> > GetPair() {return m_pair;} \n "
" private: \n "
" std::pair< std::vector<int>,std::vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " class A { \n "
" public: \n "
" A(){} \n "
" const std::pair< std::vector<int>,std::vector<int> >& GetPair() {return m_pair;} \n "
" private: \n "
" std::pair< std::vector<int>,std::vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " class A { \n "
" public: \n "
" A(){} \n "
" std::pair< std::vector<int>,std::vector<int> >& GetPair() {return m_pair;} \n "
" private: \n "
" std::pair< std::vector<int>,std::vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair< vector<int>, vector<int> > GetPair() {return m_pair;} \n "
" private: \n "
" pair< vector<int>, vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" const pair< vector<int>, vector<int> >& GetPair() {return m_pair;} \n "
" private: \n "
" pair< vector<int>, vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair< vector<int>, vector<int> >& GetPair() {return m_pair;} \n "
" private: \n "
" pair< vector<int>, vector<int> > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
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 "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
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 "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
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 "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair< pair < int, char > , int > GetPair() {return m_pair;} \n "
" private: \n "
" pair< pair < int, char > , int > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" 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 "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair< pair < int, char > , int > & GetPair() {return m_pair;} \n "
" private: \n "
" pair< pair < int, char > , int > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair< int , pair < int, char > > GetPair() {return m_pair;} \n "
" private: \n "
" pair< int , pair < int, char > > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" 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 "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" pair< int , pair < int, char > > & GetPair() {return m_pair;} \n "
" private: \n "
" pair< int , pair < int, char > > m_pair; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
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 "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
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 "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
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 "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" vector<int> GetVec() {return m_Vec;} \n "
" private: \n "
" vector<int> m_Vec; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetVec' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" const vector<int>& GetVec() {return m_Vec;} \n "
" private: \n "
" vector<int> m_Vec; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::GetVec' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
checkConst ( " using namespace std; "
2010-03-27 20:41:17 +01:00
" class A { \n "
2010-03-27 14:11:46 +01:00
" public: \n "
" A(){} \n "
" vector<int>& GetVec() {return m_Vec;} \n "
" private: \n "
" vector<int> m_Vec; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-27 14:11:46 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-03-28 11:46:42 +02:00
checkConst ( " class A { \n "
" public: \n "
" int * const * foo() { return &x; } \n "
" private: \n "
" const int * x; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-03-28 11:46:42 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class A { \n "
" public: \n "
" const int ** foo() { return &x; } \n "
" private: \n "
" const int * x; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'A::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-28 11:46:42 +02:00
checkConst ( " class A { \n "
" public: \n "
" const int * const * foo() { return &x; } \n "
" private: \n "
" const int * x; \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'A::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
}
2011-10-13 20:53:06 +02:00
void const15 ( ) {
2010-03-28 15:56:13 +02:00
checkConst ( " class Fred { \n "
" unsigned long long int a; \n "
" unsigned long long int getA() { return a; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::getA' can be const. \n " , errout . str ( ) ) ;
2010-03-28 15:56:13 +02:00
// constructors can't be const..
checkConst ( " class Fred { \n "
" unsigned long long int a; \n "
" public: \n "
" Fred() { } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment through |=..
checkConst ( " class Fred { \n "
" unsigned long long int a; \n "
" unsigned long long int setA() { a |= true; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// static functions can't be const..
checkConst ( " class foo \n "
" { \n "
" public: \n "
" static unsigned long long int get() \n "
" { return 0; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const16 ( ) {
2010-04-01 16:59:35 +02:00
// ticket #1551
checkConst ( " class Fred { \n "
" int a; \n "
" void set(int i) { Fred::a = i; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const17 ( ) {
2010-04-01 17:01:52 +02:00
// ticket #1552
checkConst ( " class Fred { \n "
" public: \n "
" void set(int i, int j) { a[i].k = i; } \n "
" private: \n "
" struct { int k; } a[4]; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const18 ( ) {
2010-04-02 08:02:47 +02:00
checkConst ( " class Fred { \n "
" static int x; \n "
" public: \n "
" void set(int i) { x = i; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (performance, inconclusive) Technically the member function 'Fred::set' can be static. \n " , errout . str ( ) ) ;
2010-04-02 08:02:47 +02:00
}
2011-10-13 20:53:06 +02:00
void const19 ( ) {
2010-04-18 07:53:39 +02:00
// ticket #1612
checkConst ( " using namespace std; \n "
" class Fred { \n "
" private: \n "
" std::string s; \n "
" public: \n "
" void set(std::string ss) { s = ss; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const20 ( ) {
2010-04-18 15:40:31 +02:00
// ticket #1602
checkConst ( " class Fred { \n "
" int x : 3; \n "
" public: \n "
" void set(int i) { x = i; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" list<int *> x; \n "
" public: \n "
" list<int *> get() { return x; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" list<const int *> x; \n "
" public: \n "
" list<const int *> get() { return x; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::get' can be const. \n " , errout . str ( ) ) ;
2010-04-18 15:40:31 +02:00
checkConst ( " class Fred { \n "
" std::list<std::string &> x; \n "
" public: \n "
" std::list<std::string &> get() { return x; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" std::list<const std::string &> x; \n "
" public: \n "
" std::list<const std::string &> get() { return x; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::get' can be const. \n " , errout . str ( ) ) ;
2010-04-18 15:40:31 +02:00
}
2011-10-13 20:53:06 +02:00
void const21 ( ) {
2010-05-16 20:26:32 +02:00
// ticket #1683
checkConst ( " class A \n "
" { \n "
" private: \n "
" const char * l1[10]; \n "
" public: \n "
" A() \n "
" { \n "
" for (int i = 0 ; i < 10; l1[i] = NULL, i++); \n "
" } \n "
" void f1() { l1[0] = \" Hello \" ; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const22 ( ) {
2010-05-20 06:52:59 +02:00
checkConst ( " class A \n "
" { \n "
" private: \n "
" B::C * v1; \n "
" public: \n "
" void f1() { v1 = 0; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class A \n "
" { \n "
" private: \n "
" B::C * v1[0]; \n "
" public: \n "
" void f1() { v1[0] = 0; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const23 ( ) {
2010-05-20 17:45:10 +02:00
checkConst ( " class Class { \n "
" public: \n "
" typedef Template<double> Type; \n "
" typedef Template2<Type> Type2; \n "
" void set_member(Type2 m) { _m = m; } \n "
" private: \n "
" Type2 _m; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const24 ( ) {
2010-05-25 06:55:49 +02:00
checkConst ( " class Class { \n "
" public: \n "
" void Settings::SetSetting(QString strSetting, QString strNewVal) \n "
" { \n "
" (*m_pSettings)[strSetting] = strNewVal; \n "
" } \n "
" private: \n "
" std::map<QString, QString> *m_pSettings; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-06-03 12:51:42 +02:00
2011-10-13 20:53:06 +02:00
void const25 ( ) { // ticket #1724
2010-06-03 12:51:42 +02:00
checkConst ( " class A{ \n "
2010-06-03 18:23:16 +02:00
" public: \n "
" A(){m_strVal= " " ;} \n "
" std::string strGetString() const \n "
" {return m_strVal.c_str();} \n "
" const std::string strGetString1() const \n "
" {return m_strVal.c_str();} \n "
" private: \n "
" std::string m_strVal; \n "
" }; \n "
) ;
2010-06-03 12:51:42 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class A{ \n "
2010-06-03 18:23:16 +02:00
" public: \n "
" A(){m_strVal= " " ;} \n "
" std::string strGetString() \n "
" {return m_strVal.c_str();} \n "
" private: \n "
" std::string m_strVal; \n "
" }; \n "
) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::strGetString' can be const. \n " , errout . str ( ) ) ;
2010-06-03 12:51:42 +02:00
checkConst ( " class A{ \n "
2010-06-03 18:23:16 +02:00
" public: \n "
" A(){m_strVal= " " ;} \n "
" const std::string strGetString1() \n "
" {return m_strVal.c_str();} \n "
" private: \n "
" std::string m_strVal; \n "
" }; \n "
) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::strGetString1' can be const. \n " , errout . str ( ) ) ;
2010-06-06 12:46:08 +02:00
checkConst ( " class A{ \n "
" public: \n "
" A(){m_strVec.push_back( " " );} \n "
" size_t strGetSize() \n "
" {return m_strVec.size();} \n "
" private: \n "
" std::vector<std::string> m_strVec; \n "
" }; \n "
) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::strGetSize' can be const. \n " , errout . str ( ) ) ;
2011-07-30 15:44:20 +02:00
checkConst ( " class A{ \n "
" public: \n "
" A(){m_strVec.push_back( " " );} \n "
" bool strGetEmpty() \n "
" {return m_strVec.empty();} \n "
" private: \n "
" std::vector<std::string> m_strVec; \n "
" }; \n "
) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style, inconclusive) Technically the member function 'A::strGetEmpty' can be const. \n " , errout . str ( ) ) ;
2010-06-03 12:51:42 +02:00
}
2011-10-13 20:53:06 +02:00
void const26 ( ) { // ticket #1847
2010-07-13 08:01:57 +02:00
checkConst ( " class DelayBase { \n "
" public: \n "
" void swapSpecificDelays(int index1, int index2) { \n "
" std::swap<float>(delays_[index1], delays_[index2]); \n "
" } \n "
" float delays_[4]; \n "
" }; \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-04-18 18:51:38 +02:00
checkConst ( " struct DelayBase { \n "
" float swapSpecificDelays(int index1) { \n "
" return static_cast<float>(delays_[index1]); \n "
" } \n "
" float delays_[4]; \n "
" }; " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (style, inconclusive) Technically the member function 'DelayBase::swapSpecificDelays' can be const. \n " , errout . str ( ) ) ;
2010-07-13 08:01:57 +02:00
}
2011-10-13 20:53:06 +02:00
void const27 ( ) { // ticket #1882
2010-08-09 17:54:16 +02:00
checkConst ( " class A { \n "
" public: \n "
" A(){m_d=1.0; m_iRealVal=2.0;} \n "
" double dGetValue(); \n "
" private: \n "
" double m_d; \n "
" double m_iRealVal; \n "
" }; \n "
" double A::dGetValue() { \n "
" double dRet = m_iRealVal; \n "
" if( m_d != 0 ) \n "
" return dRet / m_d; \n "
" return dRet; \n "
" }; \n "
) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:9] -> [test.cpp:4]: (style, inconclusive) Technically the member function 'A::dGetValue' can be const. \n " , errout . str ( ) ) ;
2010-08-09 17:54:16 +02:00
}
2011-10-13 20:53:06 +02:00
void const28 ( ) { // ticket #1883
2010-07-19 13:16:11 +02:00
checkConst ( " class P { \n "
" public: \n "
" P() { x=0.0; y=0.0; } \n "
" double x,y; \n "
" }; \n "
" class A : public P { \n "
" public: \n "
" A():P(){} \n "
" void SetPos(double xPos, double yPos) { \n "
" x=xPos; \n "
" y=yPos; \n "
" } \n "
" }; \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-07-20 09:43:27 +02:00
checkConst ( " class AA : public P { \n "
" public: \n "
" AA():P(){} \n "
" inline void vSetXPos(int x_) \n "
" { \n "
" UnknownScope::x = x_; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class AA { \n "
" public: \n "
" AA():P(){} \n "
" inline void vSetXPos(int x_) \n "
" { \n "
" UnknownScope::x = x_; \n "
" } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (performance, inconclusive) Technically the member function 'AA::vSetXPos' can be static. \n " , errout . str ( ) ) ;
2010-07-20 09:43:27 +02:00
2010-07-19 13:16:11 +02:00
}
2011-10-13 20:53:06 +02:00
void const29 ( ) { // ticket #1922
2010-08-09 17:54:16 +02:00
checkConst ( " class test { \n "
" public: \n "
" test(); \n "
" const char* get() const; \n "
" char* get(); \n "
" private: \n "
" char* value_; \n "
2010-07-19 08:40:46 +02:00
" }; \n "
2010-08-09 17:54:16 +02:00
" test::test() \n "
" { \n "
" value_ = 0; \n "
" } \n "
" const char* test::get() const \n "
" { \n "
" return value_; \n "
" } \n "
" char* test::get() \n "
" { \n "
" return value_; \n "
2010-08-10 07:48:09 +02:00
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const30 ( ) {
2010-08-10 07:48:09 +02:00
// check for false negatives
checkConst ( " class Base { \n "
" public: \n "
" int a; \n "
" }; \n "
" class Derived : public Base { \n "
" public: \n "
" int get() { \n "
" return a; \n "
" } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (style, inconclusive) Technically the member function 'Derived::get' can be const. \n " , errout . str ( ) ) ;
2010-08-10 07:48:09 +02:00
checkConst ( " class Base1 { \n "
" public: \n "
" int a; \n "
" }; \n "
" class Base2 { \n "
" public: \n "
" int b; \n "
" }; \n "
" class Derived : public Base1, public Base2 { \n "
" public: \n "
" int getA() { \n "
" return a; \n "
" } \n "
" int getB() { \n "
" return b; \n "
" } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:11]: (style, inconclusive) Technically the member function 'Derived::getA' can be const. \n "
" [test.cpp:14]: (style, inconclusive) Technically the member function 'Derived::getB' can be const. \n " , errout . str ( ) ) ;
2010-08-10 07:48:09 +02:00
checkConst ( " class Base { \n "
" public: \n "
" int a; \n "
" }; \n "
" class Derived1 : public Base { }; \n "
" class Derived2 : public Derived1 { \n "
" public: \n "
" int get() { \n "
" return a; \n "
" } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (style, inconclusive) Technically the member function 'Derived2::get' can be const. \n " , errout . str ( ) ) ;
2010-08-10 07:48:09 +02:00
checkConst ( " class Base { \n "
" public: \n "
" int a; \n "
" }; \n "
" class Derived1 : public Base { }; \n "
" class Derived2 : public Derived1 { }; \n "
" class Derived3 : public Derived2 { }; \n "
" class Derived4 : public Derived3 { \n "
" public: \n "
" int get() { \n "
" return a; \n "
" } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:10]: (style, inconclusive) Technically the member function 'Derived4::get' can be const. \n " , errout . str ( ) ) ;
2010-08-10 07:48:09 +02:00
// check for false positives
checkConst ( " class Base { \n "
" public: \n "
" int a; \n "
" }; \n "
" class Derived : public Base { \n "
" public: \n "
" int get() const { \n "
" return a; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Base1 { \n "
" public: \n "
" int a; \n "
" }; \n "
" class Base2 { \n "
" public: \n "
" int b; \n "
" }; \n "
" class Derived : public Base1, public Base2 { \n "
" public: \n "
" int getA() const { \n "
" return a; \n "
" } \n "
" int getB() const { \n "
" return b; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Base { \n "
" public: \n "
" int a; \n "
" }; \n "
" class Derived1 : public Base { }; \n "
" class Derived2 : public Derived1 { \n "
" public: \n "
" int get() const { \n "
" return a; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Base { \n "
" public: \n "
" int a; \n "
" }; \n "
" class Derived1 : public Base { }; \n "
" class Derived2 : public Derived1 { }; \n "
" class Derived3 : public Derived2 { }; \n "
" class Derived4 : public Derived3 { \n "
" public: \n "
" int get() const { \n "
" return a; \n "
" } \n "
" }; \n " ) ;
2010-08-09 17:54:16 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-07-19 08:40:46 +02:00
}
2011-10-13 20:53:06 +02:00
void const31 ( ) {
2010-08-14 08:16:53 +02:00
checkConst ( " namespace std { } \n "
" class Fred { \n "
" public: \n "
" int a; \n "
" int get() { return a; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (style, inconclusive) Technically the member function 'Fred::get' can be const. \n " , errout . str ( ) ) ;
2010-08-14 08:16:53 +02:00
}
2011-10-13 20:53:06 +02:00
void const32 ( ) {
2010-08-15 08:30:21 +02:00
checkConst ( " class Fred { \n "
" public: \n "
" std::string a[10]; \n "
" void seta() { a[0] = \" \" ; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const33 ( ) {
2010-08-20 07:28:31 +02:00
checkConst ( " class derived : public base { \n "
" public: \n "
" void f(){} \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const34 ( ) { // ticket #1964
2010-08-20 19:47:41 +02:00
checkConst ( " class Bar { \n "
" void init(Foo * foo) { \n "
" foo.bar = this; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const35 ( ) { // ticket #2001
2010-08-31 17:57:42 +02:00
checkConst ( " namespace N \n "
" { \n "
" class Base \n "
" { \n "
" }; \n "
" } \n "
" namespace N \n "
" { \n "
" class Derived : public Base \n "
" { \n "
" public: \n "
" int getResourceName() { return var; } \n "
" int var; \n "
" }; \n "
" } \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:12]: (style, inconclusive) Technically the member function 'N::Derived::getResourceName' can be const. \n " , errout . str ( ) ) ;
2010-09-01 16:47:53 +02:00
checkConst ( " namespace N \n "
" { \n "
" class Base \n "
" { \n "
" public: \n "
" int getResourceName(); \n "
" int var; \n "
" }; \n "
" } \n "
" int N::Base::getResourceName() { return var; } \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:10] -> [test.cpp:6]: (style, inconclusive) Technically the member function 'N::Base::getResourceName' can be const. \n " , errout . str ( ) ) ;
2010-09-01 16:47:53 +02:00
checkConst ( " namespace N \n "
" { \n "
" class Base \n "
" { \n "
" public: \n "
" int getResourceName(); \n "
" int var; \n "
" }; \n "
" } \n "
" namespace N \n "
" { \n "
" int Base::getResourceName() { return var; } \n "
" } \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:12] -> [test.cpp:6]: (style, inconclusive) Technically the member function 'N::Base::getResourceName' can be const. \n " , errout . str ( ) ) ;
2010-09-03 06:17:34 +02:00
checkConst ( " namespace N \n "
" { \n "
" class Base \n "
" { \n "
" public: \n "
" int getResourceName(); \n "
" int var; \n "
" }; \n "
" } \n "
" using namespace N; \n "
" int Base::getResourceName() { return var; } \n " ) ;
2012-05-06 19:37:41 +02:00
TODO_ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:6]: (style, inconclusive) Technically the member function 'N::Base::getResourceName' can be const. \n " ,
2011-01-30 12:54:19 +01:00
" " , errout . str ( ) ) ;
2010-08-31 17:57:42 +02:00
}
2011-10-13 20:53:06 +02:00
void const36 ( ) { // ticket #2003
2010-09-01 06:18:09 +02:00
checkConst ( " class Foo { \n "
" public: \n "
" Blue::Utility::Size m_MaxQueueSize; \n "
" void SetMaxQueueSize(Blue::Utility::Size a_MaxQueueSize) \n "
" { \n "
" m_MaxQueueSize = a_MaxQueueSize; \n "
" } \n "
2011-03-25 12:58:51 +01:00
" }; \n " ) ;
2010-09-01 06:18:09 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const37 ( ) { // ticket #2081 and #2085
2010-10-12 07:57:09 +02:00
checkConst ( " class A \n "
" { \n "
" public: \n "
" A(){}; \n "
" std::string operator+(const char *c) \n "
" { \n "
" return m_str+std::string(c); \n "
" } \n "
" private: \n "
" std::string m_str; \n "
2011-03-25 12:58:51 +01:00
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (style, inconclusive) Technically the member function 'A::operator+' can be const. \n " , errout . str ( ) ) ;
2010-10-12 07:57:09 +02:00
checkConst ( " class Fred \n "
" { \n "
" private: \n "
" long x; \n "
" public: \n "
" Fred() { \n "
" x = 0; \n "
" } \n "
" bool isValid() { \n "
" return bool(x == 0x11224488); \n "
" } \n "
2011-03-25 12:58:51 +01:00
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:9]: (style, inconclusive) Technically the member function 'Fred::isValid' can be const. \n " , errout . str ( ) ) ;
2010-10-12 07:57:09 +02:00
}
2011-10-13 20:53:06 +02:00
void const38 ( ) { // ticket #2135
2010-10-27 19:25:34 +02:00
checkConst ( " class Foo { \n "
" public: \n "
" ~Foo() { delete oArq; } \n "
" Foo(): oArq(new std::ofstream( \" ... \" )) {} \n "
" void MyMethod(); \n "
" private: \n "
" std::ofstream *oArq; \n "
" }; \n "
" void Foo::MyMethod() \n "
" { \n "
" (*oArq) << \" </table> \" ; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const39 ( ) {
2010-11-06 20:27:12 +01:00
checkConst ( " class Foo \n "
" { \n "
" int * p; \n "
" public: \n "
" Foo () : p(0) { } \n "
" int * f(); \n "
" const int * f() const; \n "
" }; \n "
" const int * Foo::f() const \n "
" { \n "
" return p; \n "
" } \n "
" int * Foo::f() \n "
" { \n "
" return p; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const40 ( ) { // ticket #2228
2010-11-25 07:15:33 +01:00
checkConst ( " class SharedPtrHolder \n "
" { \n "
" private: \n "
" std::tr1::shared_ptr<int> pView; \n "
" public: \n "
" SharedPtrHolder() \n "
" { } \n "
" void SetView(const std::shared_ptr<int> & aView) \n "
" { \n "
" pView = aView; \n "
" } \n "
2011-03-25 12:58:51 +01:00
" }; \n " ) ;
2010-11-25 07:15:33 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const41 ( ) { // ticket #2255
2010-11-30 19:40:32 +01:00
checkConst ( " class Fred \n "
" { \n "
" ::std::string m_name; \n "
" public: \n "
" void SetName(const ::std::string & name) \n "
" { \n "
" m_name = name; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class SharedPtrHolder \n "
" { \n "
" ::std::tr1::shared_ptr<int> pNum; \n "
" public : \n "
" void SetNum(const ::std::tr1::shared_ptr<int> & apNum) \n "
" { \n "
" pNum = apNum; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class SharedPtrHolder2 \n "
" { \n "
" public: \n "
" typedef ::std::tr1::shared_ptr<int> IntSharedPtr; \n "
" private: \n "
" IntSharedPtr pNum; \n "
" public : \n "
" void SetNum(const IntSharedPtr & apNum) \n "
" { \n "
" pNum = apNum; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " struct IntPtrTypes \n "
" { \n "
" typedef ::std::tr1::shared_ptr<int> Shared; \n "
" }; \n "
" class SharedPtrHolder3 \n "
" { \n "
" private: \n "
" IntPtrTypes::Shared pNum; \n "
" public : \n "
" void SetNum(const IntPtrTypes::Shared & apNum) \n "
" { \n "
" pNum = apNum; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " template <typename T> \n "
" struct PtrTypes \n "
" { \n "
" typedef ::std::tr1::shared_ptr<T> Shared; \n "
" }; \n "
" class SharedPtrHolder4 \n "
" { \n "
" private: \n "
" PtrTypes<int>::Shared pNum; \n "
" public : \n "
" void SetNum(const PtrTypes<int>::Shared & apNum) \n "
" { \n "
" pNum = apNum; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const42 ( ) { // ticket #2282
2010-12-07 19:42:30 +01:00
checkConst ( " class Fred \n "
" { \n "
" public: \n "
" struct AB { }; \n "
" bool f(AB * ab); \n "
" }; \n "
" bool Fred::f(Fred::AB * ab) \n "
" { \n "
" } \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:7] -> [test.cpp:5]: (performance, inconclusive) Technically the member function 'Fred::f' can be static. \n " , errout . str ( ) ) ;
2010-12-07 19:42:30 +01:00
checkConst ( " class Fred \n "
" { \n "
" public: \n "
" struct AB { \n "
" struct CD { }; \n "
" }; \n "
" bool f(AB::CD * cd); \n "
" }; \n "
" bool Fred::f(Fred::AB::CD * cd) \n "
" { \n "
" } \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:9] -> [test.cpp:7]: (performance, inconclusive) Technically the member function 'Fred::f' can be static. \n " , errout . str ( ) ) ;
2010-12-07 19:42:30 +01:00
checkConst ( " namespace NS { \n "
" class Fred \n "
" { \n "
" public: \n "
" struct AB { \n "
" struct CD { }; \n "
" }; \n "
" bool f(AB::CD * cd); \n "
" }; \n "
" bool Fred::f(Fred::AB::CD * cd) \n "
" { \n "
" } \n "
" } \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:10] -> [test.cpp:8]: (performance, inconclusive) Technically the member function 'NS::Fred::f' can be static. \n " , errout . str ( ) ) ;
2010-12-07 19:42:30 +01:00
checkConst ( " namespace NS { \n "
" class Fred \n "
" { \n "
" public: \n "
" struct AB { \n "
" struct CD { }; \n "
" }; \n "
" bool f(AB::CD * cd); \n "
" }; \n "
" } \n "
" bool NS::Fred::f(NS::Fred::AB::CD * cd) \n "
" { \n "
" } \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:8]: (performance, inconclusive) Technically the member function 'NS::Fred::f' can be static. \n " , errout . str ( ) ) ;
2010-12-07 19:42:30 +01:00
checkConst ( " class Foo { \n "
" class Fred \n "
" { \n "
" public: \n "
" struct AB { \n "
" struct CD { }; \n "
" }; \n "
" bool f(AB::CD * cd); \n "
" }; \n "
" }; \n "
" bool Foo::Fred::f(Foo::Fred::AB::CD * cd) \n "
" { \n "
" } \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:8]: (performance, inconclusive) Technically the member function 'Foo::Fred::f' can be static. \n " , errout . str ( ) ) ;
2010-12-07 19:42:30 +01:00
}
2011-10-13 20:53:06 +02:00
void const43 ( ) { // ticket 2377
2010-12-30 01:29:09 +01:00
checkConst ( " class A \n "
" { \n "
" public: \n "
" void foo( AA::BB::CC::DD b ); \n "
" AA::BB::CC::DD a; \n "
" }; \n "
" void A::foo( AA::BB::CC::DD b ) \n "
" { \n "
" a = b; \n "
" } \n " ) ;
2010-12-30 07:47:05 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-30 01:44:46 +01:00
checkConst ( " namespace AA \n "
" { \n "
" namespace BB \n "
" { \n "
" namespace CC \n "
" { \n "
" struct DD \n "
" {}; \n "
" } \n "
" } \n "
" } \n "
" class A \n "
" { \n "
" public: \n "
" \n "
" AA::BB::CC::DD a; \n "
" void foo(AA::BB::CC::DD b) \n "
" { \n "
" a = b; \n "
" } \n "
" }; \n " ) ;
2010-12-30 07:47:05 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-30 01:44:46 +01:00
checkConst ( " namespace ZZ \n "
" { \n "
" namespace YY \n "
" { \n "
" struct XX \n "
" {}; \n "
" } \n "
" } \n "
" class B \n "
" { \n "
" public: \n "
" ZZ::YY::XX a; \n "
" void foo(ZZ::YY::XX b) \n "
" { \n "
" a = b; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-30 01:29:09 +01:00
}
2011-10-13 20:53:06 +02:00
void const44 ( ) { // ticket 2595
2011-02-21 02:01:54 +01:00
checkConst ( " class A \n "
" { \n "
" public: \n "
" bool bOn; \n "
" bool foo() \n "
" { \n "
" return 0 != (bOn = bOn && true); \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const45 ( ) { // ticket 2664
2011-03-20 17:53:37 +01:00
checkConst ( " namespace wraps { \n "
" class BaseLayout {}; \n "
" } \n "
" namespace tools { \n "
" class WorkspaceControl : \n "
" public wraps::BaseLayout \n "
" { \n "
" int toGrid(int _value) \n "
" { \n "
" } \n "
" }; \n "
" } \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (performance, inconclusive) Technically the member function 'tools::WorkspaceControl::toGrid' can be static. \n " , errout . str ( ) ) ;
2011-03-20 17:53:37 +01:00
}
2011-10-13 20:53:06 +02:00
void const46 ( ) { // ticket 2663
2011-03-20 18:29:52 +01:00
checkConst ( " class Altren { \n "
" public: \n "
" int fun1() { \n "
" int a; \n "
" a++; \n "
" } \n "
" int fun2() { \n "
" b++; \n "
" } \n "
2011-03-25 12:58:51 +01:00
" }; \n " ) ;
2011-03-20 18:29:52 +01:00
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Altren::fun1' can be static. \n "
" [test.cpp:7]: (performance, inconclusive) Technically the member function 'Altren::fun2' can be static. \n " , errout . str ( ) ) ;
2011-03-20 18:29:52 +01:00
}
2011-10-13 20:53:06 +02:00
void const47 ( ) { // ticket 2670
2011-03-23 00:23:36 +01:00
checkConst ( " class Altren { \n "
" public: \n "
" void foo() { delete this; } \n "
" void foo(int i) const { } \n "
" void bar() { foo(); } \n "
2011-03-25 12:58:51 +01:00
" }; \n " ) ;
2011-03-23 00:23:36 +01:00
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (performance, inconclusive) Technically the member function 'Altren::foo' can be static. \n " , errout . str ( ) ) ;
2011-03-23 00:23:36 +01:00
checkConst ( " class Altren { \n "
" public: \n "
" void foo() { delete this; } \n "
" void foo(int i) const { } \n "
" void bar() { foo(1); } \n "
2011-03-25 12:58:51 +01:00
" }; \n " ) ;
2011-03-23 00:23:36 +01:00
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (performance, inconclusive) Technically the member function 'Altren::foo' can be static. \n "
" [test.cpp:5]: (style, inconclusive) Technically the member function 'Altren::bar' can be const. \n " , errout . str ( ) ) ;
2011-03-23 00:23:36 +01:00
}
2011-10-13 20:53:06 +02:00
void const48 ( ) { // ticket 2672
2011-03-24 01:19:32 +01:00
checkConst ( " class S0 { \n "
" class S1 { \n "
" class S2 { \n "
" class S3 { \n "
" class S4 { }; \n "
" }; \n "
" }; \n "
" }; \n "
" }; \n "
" class TextIterator { \n "
" S0::S1::S2::S3::S4 mCurrent, mSave; \n "
" public: \n "
" bool setTagColour(); \n "
" }; \n "
" bool TextIterator::setTagColour() { \n "
" mSave = mCurrent; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const49 ( ) { // ticket 2795
2011-06-04 04:00:27 +02:00
checkConst ( " class A { \n "
" private: \n "
" std::map<unsigned int,unsigned int> _hash; \n "
" public: \n "
" A() : _hash() {} \n "
2012-07-16 14:02:33 +02:00
" unsigned int fetch(unsigned int key) \n " // cannot be 'const'
2011-06-04 04:00:27 +02:00
" { \n "
" return _hash[key]; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const50 ( ) { // ticket 2943
2011-07-27 17:23:22 +02:00
checkConst ( " class Altren \n "
" { \n "
" class SubClass : public std::vector<int> \n "
" { \n "
" }; \n "
" }; \n "
" void _setAlign() \n "
" { \n "
" if (mTileSize.height > 0) return; \n "
" if (mEmptyView) return; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void const51 ( ) { // ticket 3040
2011-08-23 02:34:00 +02:00
checkConst ( " class PSIPTable { \n "
" public: \n "
" PSIPTable() : _pesdata(0) { } \n "
" const unsigned char* pesdata() const { return _pesdata; } \n "
" unsigned char* pesdata() { return _pesdata; } \n "
" void SetSection(uint num) { pesdata()[6] = num; } \n "
" private: \n "
" unsigned char *_pesdata; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class PESPacket { \n "
" public: \n "
" PESPacket() : _pesdata(0) { } \n "
" const unsigned char* pesdata() const { return _pesdata; } \n "
" unsigned char* pesdata() { return _pesdata; } \n "
" private: \n "
" unsigned char *_pesdata; \n "
" }; \n "
" class PSIPTable : public PESPacket \n "
" { \n "
" public: \n "
" void SetSection(uint num) { pesdata()[6] = num; } \n "
" }; \n " ) ;
2011-08-26 01:13:53 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-12-15 20:18:52 +01:00
void const52 ( ) { // ticket 3048
checkConst ( " class foo { \n "
" void DoSomething(int &a) const { a = 1; } \n "
" void DoSomethingElse() { DoSomething(bar); } \n "
" private: \n "
" int bar; \n "
" }; " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (performance, inconclusive) Technically the member function 'foo::DoSomething' can be static. \n " , errout . str ( ) ) ;
2011-12-15 20:18:52 +01:00
}
void const53 ( ) { // ticket 3049
2011-08-26 01:13:53 +02:00
checkConst ( " class A { \n "
" public: \n "
" A() : foo(false) {}; \n "
" virtual bool One(bool b = false) { foo = b; return false; } \n "
" private: \n "
" bool foo; \n "
" }; \n "
" class B : public A { \n "
" public: \n "
" B() {}; \n "
" bool One(bool b = false) { return false; } \n "
" }; \n " ) ;
2011-08-28 15:21:00 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-12-15 20:18:52 +01:00
void const54 ( ) { // ticket 3052
2011-08-28 15:21:00 +02:00
checkConst ( " class Example { \n "
" public: \n "
" void Clear(void) { Example tmp; (*this) = tmp; } \n "
" }; \n " ) ;
2011-09-17 00:07:25 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-12-15 20:18:52 +01:00
void const55 ( ) {
2011-09-17 00:07:25 +02:00
checkConst ( " class MyObject { \n "
" int tmp; \n "
" MyObject() : tmp(0) {} \n "
" public: \n "
" void set(std::stringstream &in) { in >> tmp; } \n "
" }; \n " ) ;
2011-08-23 02:34:00 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-12-15 20:18:52 +01:00
void const56 ( ) { // ticket #3149
2011-09-30 02:16:52 +02:00
checkConst ( " class MyObject { \n "
" public: \n "
" void foo(int x) { \n "
" switch (x) { } \n "
" } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'MyObject::foo' can be static. \n " , errout . str ( ) ) ;
2011-09-30 17:16:34 +02:00
checkConst ( " class A \n "
" { \n "
" protected: \n "
" unsigned short f (unsigned short X); \n "
" public: \n "
" A (); \n "
" }; \n "
" \n "
" unsigned short A::f (unsigned short X) \n "
" { \n "
" enum ERetValues {RET_NOK = 0, RET_OK = 1}; \n "
" enum ETypes {FLOAT_TYPE = 1, INT_TYPE = 2}; \n "
" \n "
" try \n "
" { \n "
" switch (X) \n "
" { \n "
" case FLOAT_TYPE: \n "
" { \n "
" return RET_OK; \n "
" break; \n "
" } \n "
" case INT_TYPE: \n "
" { \n "
" return RET_OK; \n "
" break; \n "
" } \n "
" default: \n "
" { \n "
" return RET_NOK; \n "
" break; \n "
" } \n "
" } \n "
" } \n "
" catch (...) \n "
" { \n "
" return RET_NOK; \n "
" } \n "
" \n "
" return RET_NOK; \n "
" } \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:9] -> [test.cpp:4]: (performance, inconclusive) Technically the member function 'A::f' can be static. \n " , errout . str ( ) ) ;
2011-09-30 22:26:08 +02:00
checkConst ( " class MyObject { \n "
" public: \n "
" void foo(int x) { \n "
" for (int i = 0; i < 5; i++) { } \n "
" } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'MyObject::foo' can be static. \n " , errout . str ( ) ) ;
2011-09-30 02:16:52 +02:00
}
2012-05-17 11:15:21 +02:00
void const57 ( ) { // tickets #2669 and #2477
2012-04-17 00:31:32 +02:00
checkConst ( " namespace MyGUI \n "
" { \n "
" namespace types \n "
" { \n "
" struct TSize {}; \n "
" struct TCoord { \n "
" TSize size() const { } \n "
" }; \n "
" } \n "
" typedef types::TSize IntSize; \n "
" typedef types::TCoord IntCoord; \n "
" } \n "
" class SelectorControl \n "
" { \n "
" MyGUI::IntSize getSize() \n "
" { \n "
" return mCoordValue.size(); \n "
" } \n "
" private: \n "
" MyGUI::IntCoord mCoordValue; \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (performance, inconclusive) Technically the member function 'MyGUI::types::TCoord::size' can be static. \n "
" [test.cpp:15]: (style, inconclusive) Technically the member function 'SelectorControl::getSize' can be const. \n " , errout . str ( ) ) ;
2012-05-17 11:15:21 +02:00
checkConst ( " struct Foo { \n "
" Bar b; \n "
" void foo(Foo f) { \n "
" b.run(); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " struct Bar { \n "
" int i = 0; \n "
" void run() { i++; } \n "
" }; \n "
" struct Foo { \n "
" Bar b; \n "
" void foo(Foo f) { \n "
" b.run(); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-04-17 00:31:32 +02:00
2012-05-17 11:15:21 +02:00
checkConst ( " struct Bar { \n "
" void run() const { } \n "
" }; \n "
" struct Foo { \n "
" Bar b; \n "
" void foo(Foo f) { \n "
" b.run(); \n "
" } \n "
" }; " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (performance, inconclusive) Technically the member function 'Bar::run' can be static. \n "
" [test.cpp:6]: (style, inconclusive) Technically the member function 'Foo::foo' can be const. \n " , errout . str ( ) ) ;
2012-04-17 00:31:32 +02:00
}
2012-05-16 21:36:05 +02:00
void const58 ( ) {
checkConst ( " struct MyObject { \n "
" void foo(Foo f) { \n "
" f.clear(); \n "
" } \n "
" }; " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (performance, inconclusive) Technically the member function 'MyObject::foo' can be static. \n " , errout . str ( ) ) ;
2012-05-16 21:36:05 +02:00
checkConst ( " struct MyObject { \n "
" int foo(Foo f) { \n "
" return f.length(); \n "
" } \n "
" }; " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (performance, inconclusive) Technically the member function 'MyObject::foo' can be static. \n " , errout . str ( ) ) ;
2012-05-16 21:36:05 +02:00
checkConst ( " struct MyObject { \n "
" Foo f; \n "
" int foo() { \n "
" return f.length(); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " struct MyObject { \n "
" std::string f; \n "
" int foo() { \n "
" return f.length(); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (style, inconclusive) Technically the member function 'MyObject::foo' can be const. \n " , errout . str ( ) ) ;
}
2012-05-17 10:05:36 +02:00
void const_handleDefaultParameters ( ) {
checkConst ( " struct Foo { \n "
" void foo1(int i, int j = 0) { \n "
" return func(this); \n "
" } \n "
" int bar1() { \n "
" return foo1(1); \n "
" } \n "
" int bar2() { \n "
" return foo1(1, 2); \n "
" } \n "
" int bar3() { \n "
" return foo1(1, 2, 3); \n "
" } \n "
" int bar4() { \n "
" return foo1(); \n "
" } \n "
" void foo2(int i = 0) { \n "
" return func(this); \n "
" } \n "
" int bar5() { \n "
" return foo2(); \n "
" } \n "
" void foo3() { \n "
" return func(this); \n "
" } \n "
" int bar6() { \n "
" return foo3(); \n "
" } \n "
" }; " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:11]: (performance, inconclusive) Technically the member function 'Foo::bar3' can be static. \n "
" [test.cpp:14]: (performance, inconclusive) Technically the member function 'Foo::bar4' can be static. \n " , errout . str ( ) ) ;
2012-05-17 10:05:36 +02:00
}
2012-05-17 10:49:52 +02:00
void const_passThisToMemberOfOtherClass ( ) {
checkConst ( " struct Foo { \n "
" void foo() { \n "
" Bar b; \n "
" b.takeFoo(this); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " struct Foo { \n "
" void foo() { \n "
" Foo f; \n "
" f.foo(); \n "
" } \n "
" }; " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (performance, inconclusive) Technically the member function 'Foo::foo' can be static. \n " , errout . str ( ) ) ;
2012-05-17 10:49:52 +02:00
}
2011-10-13 20:53:06 +02:00
void assigningPointerToPointerIsNotAConstOperation ( ) {
2010-12-30 22:57:43 +01:00
checkConst ( " struct s \n "
" { \n "
" int** v; \n "
" void f() \n "
" { \n "
" v = 0; \n "
" } \n "
" }; \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void assigningArrayElementIsNotAConstOperation ( ) {
2011-01-01 01:19:32 +01:00
checkConst ( " struct s \n "
" { \n "
" ::std::string v[3]; \n "
" void f() \n "
" { \n "
" v[0] = \" Happy new year! \" ; \n "
" } \n "
" }; \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-01-24 13:33:30 +01:00
// increment/decrement => not const
2011-10-13 20:53:06 +02:00
void constincdec ( ) {
2010-01-24 13:33:30 +01:00
checkConst ( " class Fred { \n "
" int a; \n "
" void nextA() { return ++a; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-30 02:05:44 +01:00
checkConst ( " class Fred { \n "
" int a; \n "
" void nextA() { return --a; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a; \n "
" void nextA() { return a++; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a; \n "
" void nextA() { return a--; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a; \n "
" class Fred { \n "
" void nextA() { return ++a; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a; \n "
" class Fred { \n "
" void nextA() { return --a; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a; \n "
" class Fred { \n "
" void nextA() { return a++; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a; \n "
" class Fred { \n "
" void nextA() { return a--; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
}
2011-10-13 20:53:06 +02:00
void constassign1 ( ) {
2011-03-26 04:02:13 +01:00
checkConst ( " class Fred { \n "
" int a; \n "
" void nextA() { return a=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-30 02:05:44 +01:00
checkConst ( " class Fred { \n "
" int a; \n "
" void nextA() { return a-=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a; \n "
" void nextA() { return a+=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a; \n "
" void nextA() { return a*=-1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a; \n "
" void nextA() { return a/=-2; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a; \n "
" class Fred { \n "
" void nextA() { return a=1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a; \n "
" class Fred { \n "
" void nextA() { return a-=1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a; \n "
" class Fred { \n "
" void nextA() { return a+=1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a; \n "
" class Fred { \n "
" void nextA() { return a*=-1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a; \n "
" class Fred { \n "
" void nextA() { return a/=-2; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2010-01-24 13:33:30 +01:00
}
2010-01-25 21:40:57 +01:00
2011-10-13 20:53:06 +02:00
void constassign2 ( ) {
2011-03-27 19:59:12 +02:00
checkConst ( " class Fred { \n "
" struct A { int a; } s; \n "
" void nextA() { return s.a=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" struct A { int a; } s; \n "
" void nextA() { return s.a-=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" struct A { int a; } s; \n "
" void nextA() { return s.a+=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" struct A { int a; } s; \n "
" void nextA() { return s.a*=-1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " struct A { int a; } s; \n "
" class Fred { \n "
" void nextA() { return s.a=1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-27 19:59:12 +02:00
checkConst ( " struct A { int a; } s; \n "
" class Fred { \n "
" void nextA() { return s.a-=1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-27 19:59:12 +02:00
checkConst ( " struct A { int a; } s; \n "
" class Fred { \n "
" void nextA() { return s.a+=1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-27 19:59:12 +02:00
checkConst ( " struct A { int a; } s; \n "
" class Fred { \n "
" void nextA() { return s.a*=-1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-27 19:59:12 +02:00
checkConst ( " struct A { int a; } s; \n "
" class Fred { \n "
" void nextA() { return s.a/=-2; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-27 19:59:12 +02:00
checkConst ( " struct A { int a; }; \n "
" class Fred { \n "
" A s; \n "
" void nextA() { return s.a=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " struct A { int a; }; \n "
" class Fred { \n "
" A s; \n "
" void nextA() { return s.a-=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " struct A { int a; }; \n "
" class Fred { \n "
" A s; \n "
" void nextA() { return s.a+=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " struct A { int a; }; \n "
" class Fred { \n "
" A s; \n "
" void nextA() { return s.a*=-1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " struct A { int a; }; \n "
" class Fred { \n "
" A s; \n "
" void nextA() { return s.a/=-2; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-03-26 03:37:32 +01:00
// increment/decrement array element => not const
2011-10-13 20:53:06 +02:00
void constincdecarray ( ) {
2011-03-26 03:37:32 +01:00
checkConst ( " class Fred { \n "
" int a[2]; \n "
" void nextA() { return ++a[0]; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a[2]; \n "
" void nextA() { return --a[0]; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a[2]; \n "
" void nextA() { return a[0]++; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a[2]; \n "
" void nextA() { return a[0]--; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a[2]; \n "
" class Fred { \n "
" void nextA() { return ++a[0]; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a[2]; \n "
" class Fred { \n "
" void nextA() { return --a[0]; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a[2]; \n "
" class Fred { \n "
" void nextA() { return a[0]++; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a[2]; \n "
" class Fred { \n "
" void nextA() { return a[0]--; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
}
2011-10-13 20:53:06 +02:00
void constassignarray ( ) {
2011-03-26 04:02:13 +01:00
checkConst ( " class Fred { \n "
" int a[2]; \n "
" void nextA() { return a[0]=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a[2]; \n "
" void nextA() { return a[0]-=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a[2]; \n "
" void nextA() { return a[0]+=1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a[2]; \n "
" void nextA() { return a[0]*=-1; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class Fred { \n "
" int a[2]; \n "
" void nextA() { return a[0]/=-2; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " int a[2]; \n "
" class Fred { \n "
" void nextA() { return a[0]=1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a[2]; \n "
" class Fred { \n "
" void nextA() { return a[0]-=1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a[2]; \n "
" class Fred { \n "
" void nextA() { return a[0]+=1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a[2]; \n "
" class Fred { \n "
" void nextA() { return a[0]*=-1; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 04:02:13 +01:00
checkConst ( " int a[2]; \n "
" class Fred { \n "
" void nextA() { return a[0]/=-2; } \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static. \n " , errout . str ( ) ) ;
2011-03-26 03:37:32 +01:00
}
2010-01-25 21:40:57 +01:00
// return pointer/reference => not const
2011-10-13 20:53:06 +02:00
void constReturnReference ( ) {
2010-01-25 21:40:57 +01:00
checkConst ( " class Fred { \n "
" int a; \n "
" int &getR() { return a; } \n "
" int *getP() { return &a; } "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-02-20 09:55:51 +01:00
// delete member variable => not const (but technically it can, it compiles without errors)
2011-10-13 20:53:06 +02:00
void constDelete ( ) {
2010-02-20 09:55:51 +01:00
checkConst ( " class Fred { \n "
" int *a; \n "
" void clean() { delete a; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-02-21 15:23:50 +01:00
2010-02-21 10:19:28 +01:00
// A function that returns LPVOID can't be const
2011-10-13 20:53:06 +02:00
void constLPVOID ( ) {
2010-02-21 10:19:28 +01:00
checkConst ( " class Fred { \n "
" LPVOID a() { return 0; }; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-09 19:15:39 +02:00
// #1579 - HDC
checkConst ( " class Fred { \n "
" HDC a() { return 0; }; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-02-21 10:19:28 +01:00
}
2010-04-19 21:18:53 +02:00
// a function that calls const functions can be const
2011-10-13 20:53:06 +02:00
void constFunc ( ) {
2010-04-19 21:18:53 +02:00
checkConst ( " class Fred { \n "
" void f() const { }; \n "
" void a() { f(); }; \n "
" }; \n " ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (performance, inconclusive) Technically the member function 'Fred::f' can be static. \n "
" [test.cpp:3]: (style, inconclusive) Technically the member function 'Fred::a' can be const. \n " , errout . str ( ) ) ;
2010-04-19 21:18:53 +02:00
// ticket #1593
2012-07-07 20:21:08 +02:00
checkConst ( " class A \n "
2010-04-19 21:18:53 +02:00
" { \n "
" std::vector<int> m_v; \n "
" public: \n "
" A(){} \n "
" unsigned int GetVecSize() {return m_v.size();} \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2012-07-07 20:21:08 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (style, inconclusive) Technically the member function 'A::GetVecSize' can be const. \n " , errout . str ( ) ) ;
2011-07-30 15:44:20 +02:00
2012-07-07 20:21:08 +02:00
checkConst ( " class A \n "
2011-07-30 15:44:20 +02:00
" { \n "
" std::vector<int> m_v; \n "
" public: \n "
" A(){} \n "
" bool GetVecEmpty() {return m_v.empty();} \n "
" }; " ) ;
2012-07-07 20:21:08 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (style, inconclusive) Technically the member function 'A::GetVecEmpty' can be const. \n " , errout . str ( ) ) ;
2010-04-19 21:18:53 +02:00
}
2010-07-18 10:18:41 +02:00
2011-10-13 20:53:06 +02:00
void constVirtualFunc ( ) {
2010-07-18 10:18:41 +02:00
// base class has no virtual function
checkConst ( " class A { }; \n "
" class B : public A { \n "
" int b; \n "
" public: \n "
" B() : b(0) { } \n "
" int func() { return b; } \n "
2010-08-12 07:38:27 +02:00
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (style, inconclusive) Technically the member function 'B::func' can be const. \n " , errout . str ( ) ) ;
2010-07-18 10:18:41 +02:00
2010-08-12 07:38:27 +02:00
checkConst ( " class A { }; \n "
" class B : public A { \n "
" int b; \n "
" public: \n "
" B() : b(0) { } \n "
" int func(); \n "
" }; \n "
" int B::func() { return b; } \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:8] -> [test.cpp:6]: (style, inconclusive) Technically the member function 'B::func' can be const. \n " , errout . str ( ) ) ;
2010-08-12 07:38:27 +02:00
2010-07-18 10:18:41 +02:00
// base class has no virtual function
checkConst ( " class A { \n "
" public: \n "
" int func(); \n "
" }; \n "
" class B : public A { \n "
" int b; \n "
" public: \n "
" B() : b(0) { } \n "
" int func() { return b; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:9]: (style, inconclusive) Technically the member function 'B::func' can be const. \n " , errout . str ( ) ) ;
2010-07-18 10:18:41 +02:00
2010-08-12 07:38:27 +02:00
checkConst ( " class A { \n "
" public: \n "
" int func(); \n "
" }; \n "
" class B : public A { \n "
" int b; \n "
" public: \n "
" B() : b(0) { } \n "
" int func(); \n "
" }; \n "
" int B::func() { return b; } \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:9]: (style, inconclusive) Technically the member function 'B::func' can be const. \n " , errout . str ( ) ) ;
2010-08-12 07:38:27 +02:00
2010-07-18 10:18:41 +02:00
// base class has virtual function
checkConst ( " class A { \n "
" public: \n "
" virtual int func(); \n "
" }; \n "
" class B : public A { \n "
" int b; \n "
" public: \n "
" B() : b(0) { } \n "
" int func() { return b; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-08-12 07:38:27 +02:00
checkConst ( " class A { \n "
" public: \n "
" virtual int func(); \n "
" }; \n "
" class B : public A { \n "
" int b; \n "
" public: \n "
" B() : b(0) { } \n "
" int func(); \n "
" }; \n "
" int B::func() { return b; } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class A { \n "
" public: \n "
" virtual int func() = 0; \n "
" }; \n "
" class B : public A { \n "
" int b; \n "
" public: \n "
" B() : b(0) { } \n "
" int func(); \n "
" }; \n "
" int B::func() { return b; } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-07-18 10:18:41 +02:00
// base class has no virtual function
checkConst ( " class A { \n "
" int a; \n "
" public: \n "
" A() : a(0) { } \n "
" int func() { return a; } \n "
" }; \n "
" class B : public A { \n "
" int b; \n "
" public: \n "
" B() : b(0) { } \n "
" int func() { return b; } \n "
" }; \n "
" class C : public B { \n "
" int c; \n "
" public: \n "
" C() : c(0) { } \n "
" int func() { return c; } \n "
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (style, inconclusive) Technically the member function 'A::func' can be const. \n "
" [test.cpp:11]: (style, inconclusive) Technically the member function 'B::func' can be const. \n "
" [test.cpp:17]: (style, inconclusive) Technically the member function 'C::func' can be const. \n " , errout . str ( ) ) ;
2010-07-18 10:18:41 +02:00
2010-08-12 07:38:27 +02:00
checkConst ( " class A { \n "
" int a; \n "
" public: \n "
" A() : a(0) { } \n "
" int func(); \n "
" }; \n "
" int A::func() { return a; } \n "
" class B : public A { \n "
" int b; \n "
" public: \n "
" B() : b(0) { } \n "
" int func(); \n "
" }; \n "
" int B::func() { return b; } \n "
" class C : public B { \n "
" int c; \n "
" public: \n "
" C() : c(0) { } \n "
" int func(); \n "
" }; \n "
" int C::func() { return c; } \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:7] -> [test.cpp:5]: (style, inconclusive) Technically the member function 'A::func' can be const. \n "
" [test.cpp:14] -> [test.cpp:12]: (style, inconclusive) Technically the member function 'B::func' can be const. \n "
" [test.cpp:21] -> [test.cpp:19]: (style, inconclusive) Technically the member function 'C::func' can be const. \n " , errout . str ( ) ) ;
2010-08-12 07:38:27 +02:00
2010-07-18 10:18:41 +02:00
// base class has virtual function
checkConst ( " class A { \n "
" int a; \n "
" public: \n "
" A() : a(0) { } \n "
" virtual int func() { return a; } \n "
" }; \n "
" class B : public A { \n "
" int b; \n "
" public: \n "
" B() : b(0) { } \n "
" int func() { return b; } \n "
" }; \n "
" class C : public B { \n "
" int c; \n "
" public: \n "
" C() : c(0) { } \n "
" int func() { return c; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-08-12 07:38:27 +02:00
checkConst ( " class A { \n "
" int a; \n "
" public: \n "
" A() : a(0) { } \n "
" virtual int func(); \n "
" }; \n "
" int A::func() { return a; } \n "
" class B : public A { \n "
" int b; \n "
" public: \n "
" B() : b(0) { } \n "
" int func(); \n "
" }; \n "
" int B::func() { return b; } \n "
" class C : public B { \n "
" int c; \n "
" public: \n "
" C() : c(0) { } \n "
" int func(); \n "
" }; \n "
" int C::func() { return c; } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-07-18 10:18:41 +02:00
// ticket #1311
checkConst ( " class X { \n "
" int x; \n "
" public: \n "
" X(int x) : x(x) { } \n "
" int getX() { return x; } \n "
" }; \n "
" class Y : public X { \n "
" int y; \n "
" public: \n "
" Y(int x, int y) : X(x), y(y) { } \n "
" int getY() { return y; } \n "
" }; \n "
" class Z : public Y { \n "
" int z; \n "
" public: \n "
" Z(int x, int y, int z) : Y(x, y), z(z) { } \n "
" int getZ() { return z; } \n "
2010-08-12 07:38:27 +02:00
" }; \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (style, inconclusive) Technically the member function 'X::getX' can be const. \n "
" [test.cpp:11]: (style, inconclusive) Technically the member function 'Y::getY' can be const. \n "
" [test.cpp:17]: (style, inconclusive) Technically the member function 'Z::getZ' can be const. \n " , errout . str ( ) ) ;
2010-08-12 07:38:27 +02:00
checkConst ( " class X { \n "
" int x; \n "
" public: \n "
" X(int x) : x(x) { } \n "
" int getX(); \n "
" }; \n "
" int X::getX() { return x; } \n "
" class Y : public X { \n "
" int y; \n "
" public: \n "
" Y(int x, int y) : X(x), y(y) { } \n "
" int getY(); \n "
" }; \n "
" int Y::getY() { return y; } \n "
" class Z : public Y { \n "
" int z; \n "
" public: \n "
" Z(int x, int y, int z) : Y(x, y), z(z) { } \n "
" int getZ(); \n "
" }; \n "
" int Z::getZ() { return z; } \n " ) ;
2012-05-06 19:37:41 +02:00
ASSERT_EQUALS ( " [test.cpp:7] -> [test.cpp:5]: (style, inconclusive) Technically the member function 'X::getX' can be const. \n "
" [test.cpp:14] -> [test.cpp:12]: (style, inconclusive) Technically the member function 'Y::getY' can be const. \n "
" [test.cpp:21] -> [test.cpp:19]: (style, inconclusive) Technically the member function 'Z::getZ' can be const. \n " , errout . str ( ) ) ;
2010-07-18 10:18:41 +02:00
}
2010-08-07 13:08:36 +02:00
2011-10-13 20:53:06 +02:00
void constIfCfg ( ) {
2012-02-17 16:09:24 +01:00
const char code [ ] = " struct foo { \n "
" int i; \n "
" void f() { \n "
//"#ifdef ABC\n"
//" i = 4;\n"
//"endif\n"
" } \n "
2010-08-07 13:08:36 +02:00
" }; " ;
Settings settings ;
2011-10-30 11:27:27 +01:00
settings . addEnabled ( " style " ) ;
2010-08-07 13:08:36 +02:00
2012-02-17 16:09:24 +01:00
checkConst ( code , & settings , true ) ;
2012-08-01 19:24:38 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance, inconclusive) Technically the member function 'foo::f' can be static. \n " , errout . str ( ) ) ;
2010-08-07 13:08:36 +02:00
2012-02-17 16:09:24 +01:00
checkConst ( code , & settings , false ) ; // TODO: Set inconclusive to true (preprocess it)
2010-08-07 13:08:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-07 16:08:44 +02:00
2011-12-14 15:37:43 +01:00
void constFriend ( ) { // ticket #1921
2010-08-07 16:08:44 +02:00
const char code [ ] = " class foo { \n "
" friend void f() { } \n "
" }; " ;
checkConst ( code ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-16 18:55:39 +02:00
2011-10-13 20:53:06 +02:00
void constUnion ( ) { // ticket #2111
2010-10-24 16:43:10 +02:00
checkConst ( " class foo { \n "
" public: \n "
" union { \n "
" int i; \n "
" float f; \n "
" } d; \n "
" void setf(float x) { \n "
" d.f = x; \n "
" } \n "
2011-03-25 12:58:51 +01:00
" }; " ) ;
2010-10-24 16:43:10 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2012-05-18 16:54:58 +02:00
void checkInitializerListOrder ( const char code [ ] ) {
2011-09-28 03:07:37 +02:00
// Clear the error log
errout . str ( " " ) ;
// Check..
Settings settings ;
settings . addEnabled ( " style " ) ;
settings . inconclusive = true ;
// Tokenize..
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
tokenizer . simplifyTokenList ( ) ;
CheckClass checkClass ( & tokenizer , & settings , this ) ;
2012-05-18 16:54:58 +02:00
checkClass . initializerListOrder ( ) ;
2011-09-28 03:07:37 +02:00
}
2012-05-18 16:54:58 +02:00
void initializerListOrder ( ) {
checkInitializerListOrder ( " class Fred { \n "
" int a, b, c; \n "
" public: \n "
" Fred() : c(0), b(0), a(0) { } \n "
" }; " ) ;
2012-07-09 11:11:05 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:2]: (style, inconclusive) Member variable 'Fred::b' is in the wrong place in the initializer list. \n "
" [test.cpp:4] -> [test.cpp:2]: (style, inconclusive) Member variable 'Fred::a' is in the wrong place in the initializer list. \n " , errout . str ( ) ) ;
2011-09-28 03:07:37 +02:00
}
2012-05-18 16:54:58 +02:00
void checkInitializationListUsage ( const char code [ ] ) {
// Clear the error log
errout . str ( " " ) ;
// Check..
Settings settings ;
settings . addEnabled ( " performance " ) ;
// Tokenize..
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
tokenizer . simplifyTokenList ( ) ;
CheckClass checkClass ( & tokenizer , & settings , this ) ;
checkClass . initializationListUsage ( ) ;
}
void initializerListUsage ( ) {
checkInitializationListUsage ( " class Fred { \n "
2012-06-06 12:03:51 +02:00
" int a; \n " // No message for builtin types: No performance gain
" int* b; \n " // No message for pointers: No performance gain
" Fred() { a = 0; b = 0; } \n "
2012-05-18 16:54:58 +02:00
" }; " ) ;
2012-06-06 12:03:51 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-05-18 16:54:58 +02:00
checkInitializationListUsage ( " class Fred { \n "
" std::string s; \n "
" Fred() { a = 0; s = \" foo \" ; } \n "
" }; " ) ;
2012-07-31 21:28:42 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance) Variable 's' is assigned in constructor body. Consider performing initialization in initialization list. \n " , errout . str ( ) ) ;
2012-05-18 16:54:58 +02:00
checkInitializationListUsage ( " class Fred { \n "
2012-06-06 12:03:51 +02:00
" std::vector<int> v; \n "
" Fred() { v = unknown; } \n "
" }; " ) ;
2012-07-31 21:28:42 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance) Variable 'v' is assigned in constructor body. Consider performing initialization in initialization list. \n " , errout . str ( ) ) ;
2012-06-06 12:03:51 +02:00
checkInitializationListUsage ( " class C { std::string s; }; \n "
" class Fred { \n "
" C c; \n "
" Fred() { c = unknown; } \n "
" }; " ) ;
2012-07-31 21:28:42 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (performance) Variable 'c' is assigned in constructor body. Consider performing initialization in initialization list. \n " , errout . str ( ) ) ;
2012-06-06 12:03:51 +02:00
checkInitializationListUsage ( " class C; \n "
" class Fred { \n "
" C c; \n "
" Fred() { c = unknown; } \n "
" }; " ) ;
2012-07-31 21:28:42 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (performance) Variable 'c' is assigned in constructor body. Consider performing initialization in initialization list. \n " , errout . str ( ) ) ;
2012-06-06 12:03:51 +02:00
checkInitializationListUsage ( " class C; \n "
" class Fred { \n "
" C a; \n "
2012-05-18 16:54:58 +02:00
" Fred() { initB(); a = b; } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-06-06 12:03:51 +02:00
checkInitializationListUsage ( " class C; \n "
" class Fred { \n "
" C a; \n "
2012-05-18 16:54:58 +02:00
" Fred() : a(0) { if(b) a = 0; } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-06-06 12:03:51 +02:00
checkInitializationListUsage ( " class C; \n "
" class Fred { \n "
" C a[5]; \n "
2012-05-18 16:54:58 +02:00
" Fred() { for(int i = 0; i < 5; i++) a[i] = 0; } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-06-06 12:03:51 +02:00
checkInitializationListUsage ( " class C; \n "
" class Fred { \n "
" C a; int b; \n "
2012-07-31 21:28:42 +02:00
" Fred() : b(5) { a = b; } \n " // Don't issue a message here: You actually could move it to the initialization list, but it would cause problems if you change the order of the variable declarations.
2012-05-18 16:54:58 +02:00
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-05-22 10:35:56 +02:00
2012-06-06 12:03:51 +02:00
checkInitializationListUsage ( " class C; \n "
" class Fred { \n "
" C a; \n "
2012-05-22 10:35:56 +02:00
" Fred() { try { a = new int; } catch(...) {} } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-07-23 17:16:47 +02:00
checkInitializationListUsage ( " class Fred { \n "
" std::string s; \n "
" Fred() { s = toString((size_t)this); } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkInitializationListUsage ( " class Fred { \n "
" std::string a; \n "
" std::string foo(); \n "
" Fred() { a = foo(); } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkInitializationListUsage ( " class Fred { \n "
" std::string a; \n "
" Fred() { a = foo(); } \n "
" }; " ) ;
2012-07-31 21:28:42 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance) Variable 'a' is assigned in constructor body. Consider performing initialization in initialization list. \n " , errout . str ( ) ) ;
2012-05-18 16:54:58 +02:00
}
2008-12-18 22:28:57 +01:00
} ;
2009-01-05 16:49:57 +01:00
REGISTER_TEST ( TestClass )