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
2010-04-13 21:23:17 +02:00
* Copyright ( C ) 2007 - 2010 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 ;
class TestClass : public TestFixture
{
public :
TestClass ( ) : TestFixture ( " TestClass " )
{ }
private :
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
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
TEST_CASE ( uninitVar1 ) ;
2009-12-11 21:34:04 +01:00
TEST_CASE ( uninitVar2 ) ;
2010-03-29 20:34:47 +02:00
TEST_CASE ( uninitVar3 ) ;
2010-04-02 07:36:18 +02:00
TEST_CASE ( uninitVar4 ) ;
2010-04-09 18:35:54 +02:00
TEST_CASE ( uninitVar5 ) ;
2010-06-06 08:29:35 +02:00
TEST_CASE ( uninitVar6 ) ;
2010-06-24 20:09:26 +02:00
TEST_CASE ( uninitVar7 ) ;
2010-06-25 07:56:40 +02:00
TEST_CASE ( uninitVar8 ) ;
2010-07-17 12:26:05 +02:00
TEST_CASE ( uninitVar9 ) ; // ticket #1730
2010-08-29 16:36:10 +02:00
TEST_CASE ( uninitVar10 ) ; // ticket #1993
2010-09-09 07:21:51 +02:00
TEST_CASE ( uninitVar11 ) ;
2010-10-10 07:57:26 +02:00
TEST_CASE ( uninitVar12 ) ; // ticket #2078
2010-10-27 19:28:15 +02:00
TEST_CASE ( uninitVar13 ) ; // ticket #1195
2010-11-02 18:28:55 +01:00
TEST_CASE ( uninitVar14 ) ; // ticket #2149
2010-12-03 07:35:06 +01:00
TEST_CASE ( uninitVar15 ) ;
2010-12-04 17:47:00 +01:00
TEST_CASE ( uninitVar16 ) ;
2010-12-04 20:24:13 +01:00
TEST_CASE ( uninitVar17 ) ;
2009-02-09 08:47:41 +01:00
TEST_CASE ( uninitVarEnum ) ;
2009-01-17 21:17:57 +01:00
TEST_CASE ( uninitVarStream ) ;
2009-06-05 02:34:12 +02:00
TEST_CASE ( uninitVarTypedef ) ;
2010-03-31 19:53:53 +02:00
TEST_CASE ( uninitVarMemset ) ;
2009-12-13 09:35:08 +01:00
TEST_CASE ( uninitVarArray1 ) ;
TEST_CASE ( uninitVarArray2 ) ;
2010-02-10 19:28:51 +01:00
TEST_CASE ( uninitVarArray3 ) ;
2010-03-13 20:24:39 +01:00
TEST_CASE ( uninitVarArray4 ) ;
2010-05-15 20:24:11 +02:00
TEST_CASE ( uninitVarArray5 ) ;
2010-06-29 12:51:18 +02:00
TEST_CASE ( uninitVarArray6 ) ;
2010-01-12 21:36:40 +01:00
TEST_CASE ( uninitVarArray2D ) ;
2010-12-02 07:35:01 +01:00
TEST_CASE ( uninitVarStruct1 ) ; // ticket #2172
TEST_CASE ( uninitVarStruct2 ) ; // ticket #838
2010-07-14 18:50:29 +02:00
TEST_CASE ( uninitMissingFuncDef ) ; // can't expand function in constructor
TEST_CASE ( privateCtor1 ) ; // If constructor is private..
TEST_CASE ( privateCtor2 ) ; // If constructor is private..
TEST_CASE ( function ) ; // Function is not variable
TEST_CASE ( uninitVarHeader1 ) ; // Class is defined in header
TEST_CASE ( uninitVarHeader2 ) ; // Class is defined in header
TEST_CASE ( uninitVarHeader3 ) ; // Class is defined in header
TEST_CASE ( uninitVarPublished ) ; // Borland C++: Variables in the published section are auto-initialized
TEST_CASE ( uninitOperator ) ; // No FP about uninitialized 'operator[]'
TEST_CASE ( uninitFunction1 ) ; // No FP when initialized in function
TEST_CASE ( uninitFunction2 ) ; // No FP when initialized in function
TEST_CASE ( uninitFunction3 ) ; // No FP when initialized in function
TEST_CASE ( uninitSameClassName ) ; // No FP when two classes have the same name
TEST_CASE ( uninitFunctionOverload ) ; // No FP when there are overloaded functions
2010-10-23 10:56:30 +02:00
TEST_CASE ( uninitJava ) ; // Java: no FP when variable is initialized in declaration
2009-08-31 19:40:49 +02:00
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 ) ;
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
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
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
2010-04-02 08:02:47 +02:00
TEST_CASE ( const18 ) ; // ticket #1563
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
2010-12-30 22:57:43 +01:00
TEST_CASE ( assigningPointerToPointerIsNotAConstOperation ) ;
2010-04-02 22:03:07 +02:00
TEST_CASE ( constoperator1 ) ; // operator< can often be const
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 ) ;
2010-01-24 13:33:30 +01:00
TEST_CASE ( constincdec ) ; // increment/decrement => non-const
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
2010-10-24 16:43:10 +02:00
TEST_CASE ( constUnion ) ; // ticket #2111 - fp when there are union
2010-08-16 18:55:39 +02:00
TEST_CASE ( symboldatabase1 ) ;
2010-08-18 22:42:04 +02:00
TEST_CASE ( symboldatabase2 ) ;
2010-08-31 17:51:10 +02:00
TEST_CASE ( symboldatabase3 ) ; // ticket #2000
2010-11-03 20:33:07 +01:00
TEST_CASE ( symboldatabase4 ) ;
2010-11-08 19:47:19 +01:00
TEST_CASE ( symboldatabase5 ) ; // ticket #2178
2010-11-23 07:31:15 +01:00
TEST_CASE ( symboldatabase6 ) ; // ticket #2221
2010-11-25 07:43:39 +01:00
TEST_CASE ( symboldatabase7 ) ; // ticket #2230
2010-11-30 19:52:42 +01:00
TEST_CASE ( symboldatabase8 ) ; // ticket #2252
2009-08-09 19:57:48 +02:00
}
// Check the operator Equal
void checkOpertorEq ( const char code [ ] )
{
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
settings . _checkCodingStyle = true ;
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 ( ) ;
}
void operatorEq1 ( )
{
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 " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (style) 'operator=' should return something \n " , errout . str ( ) ) ;
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 " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (style) 'operator=' should return something \n "
" [test.cpp:9]: (style) 'operator=' should return something \n " , errout . str ( ) ) ;
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 " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (style) 'operator=' should return something \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2009-12-31 13:44:03 +01:00
// Check that operator Equal returns reference to this
void checkOpertorEqRetRefThis ( const char code [ ] )
{
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
settings . _checkCodingStyle = true ;
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 ( ) ;
}
2010-01-29 16:04:27 +01: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 " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (style) 'operator=' should return reference to self \n " , errout . str ( ) ) ;
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 " ) ;
ASSERT_EQUALS ( " [test.cpp:6]: (style) 'operator=' should return reference to self \n " , errout . str ( ) ) ;
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 " ) ;
ASSERT_EQUALS ( " [test.cpp:6]: (style) 'operator=' should return reference to self \n " , errout . str ( ) ) ;
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 " ) ;
ASSERT_EQUALS ( " [test.cpp:7]: (style) 'operator=' should return reference to self \n " , 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 *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 " ) ;
ASSERT_EQUALS ( " [test.cpp:10]: (style) 'operator=' should return reference to self \n " , errout . str ( ) ) ;
}
2010-01-29 16:04:27 +01:00
void operatorEqRetRefThis2 ( )
{
// ticket # 1323
checkOpertorEqRetRefThis (
" class szp \n "
" { \n "
" szp &operator =(int *other) {}; \n "
" }; " ) ;
2010-04-01 16:40:12 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) 'operator=' should return reference to self \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) {} " ) ;
2010-04-06 18:26:29 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (style) 'operator=' should return reference to self \n " , errout . str ( ) ) ;
2010-01-29 16:04:27 +01:00
}
2010-02-17 22:46:03 +01:00
void operatorEqRetRefThis3 ( )
{
// ticket # 1405
checkOpertorEqRetRefThis (
" class A { \n "
" public: \n "
" inline A &operator =(int *other) { return (*this;) }; \n "
" inline A &operator =(long *other) { return (*this = 0;) }; \n "
" }; " ) ;
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 "
" A &A::operator =(int *other) { return (*this;) }; \n "
" A &A::operator =(long *other) { return (*this = 0;) }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkOpertorEqRetRefThis (
" class A { \n "
" public: \n "
" inline A &operator =(int *other) { return (*this;) }; \n "
" 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 "
" A &A::operator =(int *other) { return (*this;) }; \n "
" A &A::operator =(long *other) { return operator = (*(int *)other); }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-02-17 22:46:03 +01:00
}
2010-02-25 07:26:59 +01:00
void operatorEqRetRefThis4 ( )
{
// 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
2010-04-01 16:40:12 +02:00
void operatorEqRetRefThis5 ( )
{
// ticket # 1550
checkOpertorEqRetRefThis (
" class A { \n "
" public: \n "
" A & operator=(const A &a) { } \n "
" }; " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (style) 'operator=' should return reference to self \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) { } " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (style) 'operator=' should return reference to self \n " , errout . str ( ) ) ;
2010-04-01 16:40:12 +02:00
}
2009-12-31 13:44:03 +01:00
// Check that operator Equal checks for assignment to self
void checkOpertorEqToSelf ( const char code [ ] )
{
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
settings . _checkCodingStyle = true ;
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 ( ) ;
}
2010-01-03 08:26:02 +01:00
void operatorEqToSelf1 ( )
2009-12-31 13:44:03 +01:00
{
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 " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (warning) 'operator=' should check for assignment to self \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 " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (warning) 'operator=' should check for assignment to self \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
2010-01-03 08:26:02 +01:00
void operatorEqToSelf2 ( )
{
// 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 " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (warning) 'operator=' should check for assignment to self \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 " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:11]: (warning) 'operator=' should check for assignment to self \n " , errout . str ( ) ) ;
2010-01-03 08:26:02 +01:00
}
void operatorEqToSelf3 ( )
{
// 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 ( ) ) ;
}
void operatorEqToSelf4 ( )
{
// 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
}
2010-01-08 19:15:24 +01:00
void operatorEqToSelf5 ( )
{
// 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 ( ) ) ;
2010-01-08 19:15:24 +01:00
}
2010-03-31 17:09:59 +02:00
void operatorEqToSelf6 ( )
{
// 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 "
" }; " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (warning) 'operator=' should check for assignment to self \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 "
" }; " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (warning) 'operator=' should check for assignment to self \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 "
" }; " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (warning) 'operator=' should check for assignment to self \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 "
" }; " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (warning) 'operator=' should check for assignment to self \n " , errout . str ( ) ) ;
2010-03-31 17:09:59 +02:00
}
2010-09-11 08:23:30 +02:00
void operatorEqToSelf7 ( )
{
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 ( ) ) ;
}
2010-11-09 06:58:19 +01:00
void operatorEqToSelf8 ( )
{
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 ( ) ) ;
}
2008-12-18 22:28:57 +01:00
// Check that base classes have virtual destructors
void checkVirtualDestructor ( const char code [ ] )
{
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
settings . inconclusive = true ;
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 ( ) ;
}
void virtualDestructor1 ( )
{
2009-01-05 16:49:57 +01:00
// Base class not found
2008-12-18 22:28:57 +01:00
checkVirtualDestructor ( " class Derived : public Base { }; " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
checkVirtualDestructor ( " class Derived : Base { }; " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01: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 "
" class Derived : public Base { public: ~Derived() { (void)11; } }; " ) ;
2010-08-09 21:22:46 +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 ( ) ) ;
checkVirtualDestructor ( " class Base { }; \n "
" class Derived : protected Base { public: ~Derived() { (void)11; } }; " ) ;
TODO_ASSERT_EQUALS ( " [test.cpp:1]: (error) Class Base which is inherited by class Derived does not have a virtual destructor \n " , errout . str ( ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkVirtualDestructor ( " class Base { }; \n "
" class Derived : private Base { public: ~Derived() { (void)11; } }; " ) ;
2010-05-29 11:19:28 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
checkVirtualDestructor ( " class Base { }; \n "
" class Derived : Base { public: ~Derived() { (void)11; } }; " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01: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 "
" class Derived : public Base { public: ~Derived() { (void)11; } }; " ) ;
2010-08-09 21:22:46 +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 ( ) ) ;
checkVirtualDestructor ( " class Base { public: ~Base(); }; \n "
" class Derived : protected Base { public: ~Derived() { (void)11; } }; " ) ;
TODO_ASSERT_EQUALS ( " [test.cpp:1]: (error) Class Base which is inherited by class Derived does not have a virtual destructor \n " , errout . str ( ) ) ;
2010-05-29 11:19:28 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
checkVirtualDestructor ( " class Base { public: ~Base(); }; \n "
" class Derived : private Fred, public Base { public: ~Derived() { (void)11; } }; " ) ;
2010-08-09 21:22:46 +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
}
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 "
" class Derived : public 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 "
" class Derived : private Fred, public 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
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 "
" class Derived : public Base { public: ~Derived() {} }; " ) ;
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 "
" class Derived : public Base { public: ~Derived(); }; Derived::~Derived() {} " ) ;
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
2009-05-06 22:22:26 +02:00
void virtualDestructorProtected ( )
{
// 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
2009-08-04 21:23:22 +02:00
void virtualDestructorInherited ( )
{
// 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 "
" ~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 " ) ;
TODO_ASSERT_EQUALS ( " [test.cpp:7]: (error) Class A which is inherited by class B does not have a virtual destructor \n " , errout . str ( ) ) ;
}
2009-08-10 16:58:13 +02:00
void virtualDestructorTemplate ( )
{
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 "
" }; \n " ) ;
2010-08-13 23:57:53 +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
}
2009-01-14 20:34:10 +01:00
void checkUninitVar ( const char code [ ] )
{
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
settings . _checkCodingStyle = true ;
2009-01-14 20:34:10 +01:00
// Tokenize..
2010-12-01 18:00:55 +01:00
Tokenizer tokenizer ( & settings , this ) ;
2009-01-14 20:34:10 +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-01-14 20:34:10 +01:00
checkClass . constructors ( ) ;
}
void uninitVar1 ( )
{
checkUninitVar ( " enum ECODES \n "
" { \n "
" CODE_1 = 0, \n "
" CODE_2 = 1 \n "
" }; \n "
" \n "
" class Fred \n "
" { \n "
" public: \n "
" Fred() {} \n "
" \n "
" private: \n "
" ECODES _code; \n "
2009-01-14 20:43:28 +01:00
" }; \n " ) ;
2009-01-14 20:34:10 +01:00
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:10]: (warning) Member variable 'Fred::_code' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2009-07-03 20:22:14 +02:00
checkUninitVar ( " class A{}; \n "
" \n "
" class B : public A \n "
" { \n "
" public: \n "
" B() {} \n "
" private: \n "
" float f; \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:6]: (warning) Member variable 'B::f' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2009-07-17 18:50:49 +02:00
checkUninitVar ( " class C \n "
" { \n "
" FILE *fp; \n "
" \n "
" public: \n "
" C(FILE *fp); \n "
" }; \n "
" \n "
" C::C(FILE *fp) { \n "
" C::fp = fp; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-01-14 20:34:10 +01:00
}
2009-12-11 21:34:04 +01:00
void uninitVar2 ( )
{
checkUninitVar ( " class John \n "
" { \n "
" public: \n "
" John() { (*this).i = 0; } \n "
" private: \n "
" int i; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-03-29 20:34:47 +02:00
void uninitVar3 ( )
{
2010-04-02 19:10:05 +02:00
// No FP when struct has constructor
2010-03-29 20:34:47 +02:00
checkUninitVar ( " class Foo \n "
" { \n "
" public: \n "
" Foo() { } \n "
" private: \n "
" struct Bar { \n "
" Bar(); \n "
" }; \n "
" Bar bars[2]; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-02 19:10:05 +02:00
// Using struct that doesn't have constructor
checkUninitVar ( " class Foo \n "
" { \n "
" public: \n "
" Foo() { } \n "
" private: \n "
" struct Bar { \n "
" int x; \n "
" }; \n "
" Bar bars[2]; \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (warning) Member variable 'Foo::bars' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-03-29 20:34:47 +02:00
}
2010-04-02 07:36:18 +02:00
void uninitVar4 ( )
{
checkUninitVar ( " class Foo \n "
" { \n "
" public: \n "
" Foo() { bar.x = 0; } \n "
" private: \n "
" struct Bar { \n "
" int x; \n "
" }; \n "
" struct Bar bar; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-04-09 18:35:54 +02:00
void uninitVar5 ( )
{
checkUninitVar ( " class Foo \n "
" { \n "
" public: \n "
" Foo() { } \n "
" Foo &operator=(const Foo &) \n "
" { return *this; } \n "
" static int i; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-06-06 08:29:35 +02:00
void uninitVar6 ( )
{
checkUninitVar ( " class Foo : public Bar \n "
" { \n "
" public: \n "
" Foo(int i) : Bar(mi=i) { } \n "
" private: \n "
" int mi; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-06-24 20:09:26 +02:00
void uninitVar7 ( )
{
checkUninitVar ( " class Foo { \n "
" int a; \n "
" public: \n "
" Foo() : a(0) {} \n "
" Foo& operator=(const Foo&); \n "
" void Swap(Foo& rhs); \n "
" }; \n "
" \n "
" void Foo::Swap(Foo& rhs) { \n "
" std::swap(a,rhs.a); \n "
" } \n "
" \n "
" Foo& Foo::operator=(const Foo& rhs) { \n "
" Foo copy(rhs); \n "
" copy.Swap(*this); \n "
" return *this; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-06-25 07:56:40 +02:00
void uninitVar8 ( )
{
checkUninitVar ( " class Foo { \n "
" int a; \n "
" public: \n "
" Foo() : a(0) {} \n "
" Foo& operator=(const Foo&); \n "
" }; \n "
" \n "
" Foo& Foo::operator=(const Foo& rhs) { \n "
" if (&rhs != this) \n "
" { \n "
" } \n "
" return *this; \n "
" } \n " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (warning) Member variable 'Foo::a' is not assigned a value in 'Foo::operator=' \n " , errout . str ( ) ) ;
2010-06-25 07:56:40 +02:00
}
2010-07-17 12:26:05 +02:00
void uninitVar9 ( ) // ticket #1730
{
checkUninitVar ( " class Prefs { \n "
" private: \n "
" int xasd; \n "
" public: \n "
" Prefs(wxSize size); \n "
" }; \n "
" Prefs::Prefs(wxSize size) \n "
" { \n "
" SetMinSize( wxSize( 48,48 ) ); \n "
" } \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:7]: (warning) Member variable 'Prefs::xasd' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-07-17 12:26:05 +02:00
}
2010-08-29 16:36:10 +02:00
void uninitVar10 ( ) // ticket #1993
{
checkUninitVar ( " class A { \n "
" public: \n "
" A(); \n "
" private: \n "
" int var1; \n "
" int var2; \n "
" }; \n "
" A::A() : var1(0) { } \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:8]: (warning) Member variable 'A::var2' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-08-29 16:36:10 +02:00
}
2010-09-09 07:21:51 +02:00
void uninitVar11 ( )
{
checkUninitVar ( " class A { \n "
" public: \n "
" A(int a = 0); \n "
" private: \n "
" int var; \n "
" }; \n "
" A::A(int a) { } \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:7]: (warning) Member variable 'A::var' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-09-09 07:21:51 +02:00
}
2010-10-10 07:57:26 +02:00
void uninitVar12 ( ) // ticket #2078
{
checkUninitVar ( " class Point \n "
" { \n "
" public: \n "
" Point() \n "
" { \n "
" Point(0, 0); \n "
" } \n "
" Point(int x, int y) \n "
" : x(x), y(y) \n "
" {} \n "
" int x, y; \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (warning) Member variable 'Point::x' is not initialised in the constructor. \n "
" [test.cpp:4]: (warning) Member variable 'Point::y' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-10-10 07:57:26 +02:00
}
2010-10-27 19:28:15 +02:00
void uninitVar13 ( ) // ticket #1195
{
checkUninitVar ( " class A { \n "
" private: \n "
" std::vector<int> *ints; \n "
" public: \n "
" A() \n "
" {} \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:5]: (warning) Member variable 'A::ints' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-10-27 19:28:15 +02:00
}
2010-11-02 18:28:55 +01:00
void uninitVar14 ( ) // ticket #2149
{
// no namespace
checkUninitVar ( " class Foo \n "
" { \n "
" public: \n "
" Foo(); \n "
" private: \n "
" bool mMember; \n "
" }; \n "
" Foo::Foo() \n "
" { \n "
" } \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:8]: (warning) Member variable 'Foo::mMember' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-11-02 18:28:55 +01:00
// single namespace
checkUninitVar ( " namespace Output \n "
" { \n "
" class Foo \n "
" { \n "
" public: \n "
" Foo(); \n "
" private: \n "
" bool mMember; \n "
" }; \n "
" Foo::Foo() \n "
" { \n "
" } \n "
" } \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:10]: (warning) Member variable 'Foo::mMember' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-11-02 18:28:55 +01:00
// constructor outside namespace
checkUninitVar ( " namespace Output \n "
" { \n "
" class Foo \n "
" { \n "
" public: \n "
" Foo(); \n "
" private: \n "
" bool mMember; \n "
" }; \n "
" } \n "
" Foo::Foo() \n "
" { \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// constructor outside namespace
checkUninitVar ( " namespace Output \n "
" { \n "
" class Foo \n "
" { \n "
" public: \n "
" Foo(); \n "
" private: \n "
" bool mMember; \n "
" }; \n "
" } \n "
" Output::Foo::Foo() \n "
" { \n "
" } \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:11]: (warning) Member variable 'Foo::mMember' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-11-02 18:28:55 +01:00
2010-12-15 18:45:53 +01:00
// constructor in separate namespace
2010-11-02 18:28:55 +01:00
checkUninitVar ( " namespace Output \n "
" { \n "
" class Foo \n "
" { \n "
" public: \n "
" Foo(); \n "
" private: \n "
" bool mMember; \n "
" }; \n "
" } \n "
" namespace Output \n "
" { \n "
" Foo::Foo() \n "
" { \n "
" } \n "
" } \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:13]: (warning) Member variable 'Foo::mMember' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-11-02 18:28:55 +01:00
2010-12-15 18:45:53 +01:00
// constructor in different separate namespace
2010-11-02 18:28:55 +01:00
checkUninitVar ( " namespace Output \n "
" { \n "
" class Foo \n "
" { \n "
" public: \n "
" Foo(); \n "
" private: \n "
" bool mMember; \n "
" }; \n "
" } \n "
" namespace Input \n "
" { \n "
" Foo::Foo() \n "
" { \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-15 18:45:53 +01:00
// constructor in different separate namespace (won't compile)
2010-11-02 18:28:55 +01:00
checkUninitVar ( " namespace Output \n "
" { \n "
" class Foo \n "
" { \n "
" public: \n "
" Foo(); \n "
" private: \n "
" bool mMember; \n "
" }; \n "
" } \n "
" namespace Input \n "
" { \n "
" Output::Foo::Foo() \n "
" { \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-15 18:45:53 +01:00
// constructor in nested separate namespace
2010-11-02 18:28:55 +01:00
checkUninitVar ( " namespace A \n "
" { \n "
" namespace Output \n "
" { \n "
" class Foo \n "
" { \n "
" public: \n "
" Foo(); \n "
" private: \n "
" bool mMember; \n "
" }; \n "
" } \n "
" namespace Output \n "
" { \n "
" Foo::Foo() \n "
" { \n "
" } \n "
" } \n "
" } \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:15]: (warning) Member variable 'Foo::mMember' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-11-02 18:28:55 +01:00
2010-12-15 18:45:53 +01:00
// constructor in nested different separate namespace
2010-11-02 18:28:55 +01:00
checkUninitVar ( " namespace A \n "
" { \n "
" namespace Output \n "
" { \n "
" class Foo \n "
" { \n "
" public: \n "
" Foo(); \n "
" private: \n "
" bool mMember; \n "
" }; \n "
" } \n "
" namespace Input \n "
" { \n "
" Foo::Foo() \n "
" { \n "
" } \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-15 18:45:53 +01:00
// constructor in nested different separate namespace
2010-11-02 18:28:55 +01:00
checkUninitVar ( " namespace A \n "
" { \n "
" namespace Output \n "
" { \n "
" class Foo \n "
" { \n "
" public: \n "
" Foo(); \n "
" private: \n "
" bool mMember; \n "
" }; \n "
" } \n "
" namespace Input \n "
" { \n "
" Output::Foo::Foo() \n "
" { \n "
" } \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-12-03 07:35:06 +01:00
void uninitVar15 ( )
{
checkUninitVar ( " class Fred \n "
" { \n "
" int a; \n "
" public: \n "
" Fred(); \n "
" ~Fred(); \n "
" }; \n "
" Fred::~Fred() \n "
" { \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-12-04 17:47:00 +01:00
void uninitVar16 ( )
{
checkUninitVar ( " struct Foo \n "
" { \n "
" int a; \n "
" void set(int x) { a = x; } \n "
" }; \n "
" class Bar \n "
" { \n "
" Foo foo; \n "
" public: \n "
" Bar() \n "
" { \n "
" foo.set(0); \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkUninitVar ( " struct Foo \n "
" { \n "
" int a; \n "
" void set(int x) { a = x; } \n "
" }; \n "
" class Bar \n "
" { \n "
" Foo foo; \n "
" public: \n "
" Bar() \n "
" { \n "
" } \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:10]: (warning) Member variable 'Bar::foo' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-12-04 17:47:00 +01:00
}
2010-12-04 20:24:13 +01:00
void uninitVar17 ( )
{
checkUninitVar ( " struct Foo \n "
" { \n "
" int a; \n "
" }; \n "
" class Bar \n "
" { \n "
" Foo foo[10]; \n "
" public: \n "
" Bar() \n "
" { \n "
" foo[0].a = 0; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkUninitVar ( " struct Foo \n "
" { \n "
" int a; \n "
" }; \n "
" class Bar \n "
" { \n "
" Foo foo[10]; \n "
" public: \n "
" Bar() \n "
" { \n "
" } \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:9]: (warning) Member variable 'Bar::foo' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-12-04 20:24:13 +01:00
}
2009-12-13 09:35:08 +01:00
void uninitVarArray1 ( )
2009-08-23 21:54:41 +02:00
{
checkUninitVar ( " class John \n "
" { \n "
" public: \n "
" John() {} \n "
" \n "
" private: \n "
" char name[255]; \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (warning) Member variable 'John::name' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2009-11-10 19:30:37 +01:00
2009-08-23 21:54:41 +02:00
checkUninitVar ( " class John \n "
" { \n "
" public: \n "
2009-08-25 23:42:07 +02:00
" John() {John::name[0] = ' \\ 0';} \n "
2009-08-23 21:54:41 +02:00
" \n "
" private: \n "
" char name[255]; \n "
" }; \n " ) ;
2009-08-26 22:33:23 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-08-24 17:15:29 +02:00
checkUninitVar ( " class John \n "
" { \n "
" public: \n "
" John() { strcpy(name, " " ); } \n "
" \n "
" private: \n "
" char name[255]; \n "
" }; \n " ) ;
2009-09-03 22:28:00 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-16 20:07:03 +02:00
checkUninitVar ( " class John \n "
" { \n "
" public: \n "
" John() { } \n "
" \n "
" double operator[](const unsigned long i); \n "
" }; \n " ) ;
2009-11-10 19:30:37 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-16 20:07:03 +02:00
2009-11-10 19:30:37 +01:00
checkUninitVar ( " class A; \n "
" class John \n "
" { \n "
" public: \n "
" John() { } \n "
" A a[5]; \n "
" }; \n " ) ;
2009-09-16 20:07:03 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-11-10 19:35:54 +01:00
checkUninitVar ( " class A; \n "
" class John \n "
" { \n "
" public: \n "
" John() { } \n "
" A *a[5]; \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:5]: (warning) Member variable 'John::a' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2009-09-03 22:28:00 +02:00
}
2009-12-13 09:35:08 +01:00
void uninitVarArray2 ( )
{
checkUninitVar ( " class John \n "
" { \n "
" public: \n "
" John() { *name = 0; } \n "
" \n "
" private: \n "
" char name[255]; \n "
" }; \n " ) ;
2010-01-12 21:36:40 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-02-10 19:28:51 +01:00
void uninitVarArray3 ( )
{
checkUninitVar ( " class John \n "
" { \n "
" private: \n "
" int a[100]; \n "
" int b[100]; \n "
" \n "
" public: \n "
" John() \n "
" { \n "
" memset(a,0,sizeof(a)); \n "
" memset(b,0,sizeof(b)); \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-03-13 20:24:39 +01:00
void uninitVarArray4 ( )
{
checkUninitVar ( " class John \n "
" { \n "
" private: \n "
" int a[100]; \n "
" int b[100]; \n "
" \n "
" public: \n "
" John() \n "
" { \n "
" if (snprintf(a,10, \" a \" )) { } \n "
" if (snprintf(b,10, \" b \" )) { } \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-05-15 20:24:11 +02:00
void uninitVarArray5 ( )
{
checkUninitVar ( " class Foo \n "
" { \n "
" private: \n "
" Bar bars[10]; \n "
" public: \n "
" Foo() \n "
" { } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-06-29 12:51:18 +02:00
void uninitVarArray6 ( )
{
checkUninitVar ( " class Foo \n "
" { \n "
" public: \n "
" Foo(); \n "
" static const char STR[]; \n "
" }; \n "
" const char Foo::STR[] = \" abc \" ; \n "
" Foo::Foo() { } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-01-12 21:36:40 +01:00
void uninitVarArray2D ( )
{
checkUninitVar ( " class John \n "
" { \n "
" public: \n "
" John() { a[0][0] = 0; } \n "
" \n "
" private: \n "
" char a[2][2]; \n "
" }; \n " ) ;
2009-12-13 09:35:08 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-12-02 07:35:01 +01:00
void uninitVarStruct1 ( ) // ticket #2172
{
checkUninitVar ( " class A \n "
" { \n "
" private: \n "
" struct B { \n "
" std::string str1; \n "
" std::string str2; \n "
" } \n "
" struct B b; \n "
" public: \n "
" A() { \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkUninitVar ( " class A \n "
" { \n "
" private: \n "
" struct B { \n "
" char *str1; \n "
" char *str2; \n "
" } \n "
" struct B b; \n "
" public: \n "
" A() { \n "
" } \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:10]: (warning) Member variable 'A::b' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-12-02 07:35:01 +01:00
checkUninitVar ( " class A \n "
" { \n "
" private: \n "
" struct B { \n "
" char *str1; \n "
" char *str2; \n "
" B() : str1(NULL), str2(NULL) { } \n "
" } \n "
" struct B b; \n "
" public: \n "
" A() { \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
void uninitVarStruct2 ( ) // ticket #838
{
checkUninitVar ( " struct POINT \n "
" { \n "
" int x; \n "
" int y; \n "
" }; \n "
" class Fred \n "
" { \n "
" private: \n "
" POINT p; \n "
" public: \n "
" Fred() \n "
" { } \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:11]: (warning) Member variable 'Fred::p' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-12-02 07:35:01 +01:00
checkUninitVar ( " struct POINT \n "
" { \n "
" int x; \n "
" int y; \n "
" POINT(); \n "
" }; \n "
" class Fred \n "
" { \n "
" private: \n "
" POINT p; \n "
" public: \n "
" Fred() \n "
" { } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkUninitVar ( " struct POINT \n "
" { \n "
" int x; \n "
" int y; \n "
" POINT() :x(0), y(0) { } \n "
" }; \n "
" class Fred \n "
" { \n "
" private: \n "
" POINT p; \n "
" public: \n "
" Fred() \n "
" { } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-09-03 22:28:00 +02:00
void uninitMissingFuncDef ( )
{
// Unknown member function
checkUninitVar ( " class Fred \n "
" { \n "
" public: \n "
" Fred() { Init(); } \n "
" private: \n "
" void Init(); "
" int i; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-22 18:51:25 +01:00
// Unknown non-member function (friend class)
checkUninitVar ( " class Fred \n "
" { \n "
" public: \n "
" Fred() { Init(); } \n "
" private: \n "
" friend ABC; \n "
" int i; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// Unknown non-member function (is Init a virtual function?)
checkUninitVar ( " class Fred : private ABC \n "
" { \n "
" public: \n "
" Fred() { Init(); } \n "
" private: \n "
" int i; \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (warning) Member variable 'Fred::i' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-01-22 18:51:25 +01:00
2009-09-03 22:28:00 +02:00
// Unknown non-member function
checkUninitVar ( " class Fred \n "
" { \n "
" public: \n "
" Fred() { Init(); } \n "
" private: \n "
" int i; \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (warning) Member variable 'Fred::i' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-09-12 22:40:51 +02:00
// Unknown non-member function
checkUninitVar ( " class ABC { }; \n "
" class Fred : private ABC \n "
" { \n "
" public: \n "
" Fred() { Init(); } \n "
" private: \n "
" int i; \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:5]: (warning) Member variable 'Fred::i' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-09-12 22:40:51 +02:00
2009-08-23 21:54:41 +02:00
}
2009-02-09 08:47:41 +01:00
void uninitVarEnum ( )
{
checkUninitVar ( " class Fred \n "
" { \n "
" public: \n "
" enum abc {a,b,c}; \n "
" Fred() {} \n "
" private: \n "
" unsigned int i; \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:5]: (warning) Member variable 'Fred::i' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2009-02-09 08:47:41 +01:00
}
2009-01-17 20:26:58 +01:00
void uninitVarStream ( )
{
checkUninitVar ( " #include <fstream> \n "
2009-02-09 08:47:41 +01:00
" class Foo \n "
" { \n "
" private: \n "
" int foo; \n "
2009-01-17 20:26:58 +01:00
" public: \n "
2009-02-09 08:47:41 +01:00
" Foo(std::istream &in) \n "
" { \n "
" if(!(in >> foo)) \n "
" throw 0; \n "
" } \n "
2009-01-17 20:26:58 +01:00
" }; \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-01-17 20:26:58 +01:00
}
2009-06-05 02:34:12 +02:00
void uninitVarTypedef ( )
{
checkUninitVar ( " class Foo \n "
" { \n "
" public: \n "
" typedef int * pointer; \n "
" Foo() : a(0) {} \n "
" pointer a; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-01-27 18:39:06 +01:00
2010-03-31 19:53:53 +02:00
void uninitVarMemset ( )
{
checkUninitVar ( " class Foo \n "
" { \n "
" public: \n "
" int * pointer; \n "
" Foo() { memset(this, 0, sizeof(*this)); } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-02-09 08:47:41 +01:00
void privateCtor1 ( )
2009-01-27 18:39:06 +01:00
{
checkUninitVar ( " class Foo { \n "
" int foo; \n "
" Foo() { } \n "
" }; \n " ) ;
2010-05-16 14:43:42 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-01-27 18:39:06 +01:00
}
2009-02-09 08:47:41 +01:00
void privateCtor2 ( )
{
checkUninitVar ( " class Foo \n "
" { \n "
" private: \n "
" int foo; \n "
" Foo() { } \n "
" public: \n "
" Foo(int _i) { } \n "
" }; \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:7]: (warning) Member variable 'Foo::foo' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2009-02-09 08:47:41 +01:00
}
2009-01-27 18:39:06 +01:00
2009-02-04 20:31:25 +01:00
void function ( )
{
checkUninitVar ( " class A \n "
" { \n "
" public: \n "
" A(); \n "
" int* f(int*); \n "
" }; \n "
" \n "
" A::A() \n "
" { \n "
" } \n "
" \n "
" int* A::f(int* p) \n "
" { \n "
" return p; \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-02-04 20:31:25 +01:00
}
2009-01-27 18:39:06 +01:00
2009-02-09 08:47:41 +01:00
void uninitVarHeader1 ( )
{
checkUninitVar ( " #file \" fred.h \" \n "
" class Fred \n "
" { \n "
" private: \n "
" unsigned int i; \n "
" public: \n "
" Fred(); \n "
" }; \n "
" #endfile \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
void uninitVarHeader2 ( )
{
checkUninitVar ( " #file \" fred.h \" \n "
" class Fred \n "
" { \n "
" private: \n "
" unsigned int i; \n "
" public: \n "
" Fred() { } \n "
" }; \n "
" #endfile \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [fred.h:6]: (warning) Member variable 'Fred::i' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2009-02-09 08:47:41 +01:00
}
2009-02-21 09:24:57 +01:00
void uninitVarHeader3 ( )
{
checkUninitVar ( " #file \" fred.h \" \n "
" class Fred \n "
" { \n "
" private: \n "
" mutable int i; \n "
" public: \n "
" Fred() { } \n "
" }; \n "
" #endfile \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [fred.h:6]: (warning) Member variable 'Fred::i' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2009-02-21 09:24:57 +01:00
}
2010-12-15 18:45:53 +01:00
// Borland C++: No FP for published pointers - they are automatically initialized
2009-08-31 19:40:49 +02:00
void uninitVarPublished ( )
{
checkUninitVar ( " class Fred \n "
" { \n "
" __published: \n "
" int *i; \n "
" public: \n "
" Fred() { } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-03-28 10:58:03 +02:00
}
2010-01-06 19:04:15 +01:00
void uninitOperator ( )
{
checkUninitVar ( " class Fred \n "
" { \n "
" public: \n "
" Fred() { } \n "
" int *operator [] (int index) { return 0; } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-02-21 14:35:55 +01:00
2010-03-26 17:19:33 +01:00
void uninitFunction1 ( )
{
checkUninitVar ( " class Fred \n "
" { \n "
" public: \n "
" Fred() { init(*this); } \n "
" \n "
" static void init(Fred &f) \n "
" { f.d = 0; } \n "
" \n "
" double d; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
void uninitFunction2 ( )
{
checkUninitVar ( " class Fred \n "
" { \n "
" public: \n "
" Fred() { if (!init(*this)); } \n "
" \n "
" static bool init(Fred &f) \n "
" { f.d = 0; return true; } \n "
" \n "
" double d; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-07-14 18:50:29 +02:00
void uninitFunction3 ( )
{
checkUninitVar ( " class Fred \n "
" { \n "
" public: \n "
" Fred() { if (!init()); } \n "
" \n "
" bool init() \n "
" { d = 0; return true; } \n "
" \n "
" double d; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-04-02 19:29:54 +02:00
void uninitSameClassName ( )
{
checkUninitVar ( " class B \n "
" { \n "
" public: \n "
" B(); \n "
" int j; \n "
" }; \n "
" \n "
" class A \n "
" { \n "
" class B \n "
" { \n "
" public: \n "
" B(); \n "
" int i; \n "
" }; \n "
" }; \n "
" \n "
" A::B::B() \n "
" { \n "
" i = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-05-23 20:56:51 +02:00
2010-11-02 18:28:55 +01:00
checkUninitVar ( " class B \n "
" { \n "
" public: \n "
" B(); \n "
" int j; \n "
" }; \n "
" \n "
" class A \n "
" { \n "
" class B \n "
" { \n "
" public: \n "
" B(); \n "
" int i; \n "
" }; \n "
" }; \n "
" \n "
" B::B() \n "
" { \n "
" } \n "
" \n "
" A::B::B() \n "
" { \n "
" } \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:18]: (warning) Member variable 'B::j' is not initialised in the constructor. \n "
" [test.cpp:22]: (warning) Member variable 'B::i' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-11-02 18:28:55 +01:00
2010-05-23 20:56:51 +02:00
// Ticket #1700
checkUninitVar ( " namespace n1 \n "
" { \n "
" class Foo { "
" public: \n "
2010-05-23 21:03:14 +02:00
" Foo() : i(0) { } \n "
2010-05-23 20:56:51 +02:00
" private: \n "
" int i; \n "
" }; \n "
" } \n "
" \n "
" namespace n2 \n "
" { \n "
" class Foo { "
" public: \n "
2010-05-23 21:03:14 +02:00
" Foo() { } \n "
" }; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkUninitVar ( " namespace n1 \n "
" { \n "
2010-07-15 10:16:16 +02:00
" class Foo { \n "
2010-05-23 21:03:14 +02:00
" public: \n "
" Foo(); \n "
" private: \n "
" int i; \n "
" }; \n "
" } \n "
" \n "
" n1::Foo::Foo() \n "
" { } \n "
" \n "
" namespace n2 \n "
" { \n "
2010-07-15 10:16:16 +02:00
" class Foo { \n "
2010-05-23 21:03:14 +02:00
" public: \n "
" Foo() { } \n "
" }; \n "
" } \n " ) ;
2011-01-03 19:03:42 +01:00
ASSERT_EQUALS ( " [test.cpp:11]: (warning) Member variable 'Foo::i' is not initialised in the constructor. \n " , errout . str ( ) ) ;
2010-05-23 21:03:14 +02:00
checkUninitVar ( " namespace n1 \n "
" { \n "
" class Foo { "
" public: \n "
" Foo(); \n "
" private: \n "
" int i; \n "
" }; \n "
" } \n "
" \n "
" n1::Foo::Foo() : i(0) \n "
" { } \n "
" \n "
" namespace n2 \n "
" { \n "
" class Foo { "
" public: \n "
" Foo() { } \n "
2010-05-23 20:56:51 +02:00
" }; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-02 19:29:54 +02:00
}
2010-06-13 10:23:59 +02:00
void uninitFunctionOverload ( )
{
// Ticket #1783 - overloaded "init" functions
checkUninitVar ( " class A \n "
" { \n "
" private: \n "
" int i; \n "
" \n "
" public: \n "
" A() \n "
" { \n "
" init(); \n "
" } \n "
" \n "
" void init() { init(0); } \n "
" \n "
" void init(int value) \n "
" { i = value; } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-10-28 18:01:51 +02:00
void checkUninitVarJava ( const char code [ ] )
{
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
settings . _checkCodingStyle = true ;
2010-10-28 18:01:51 +02:00
// Tokenize..
2010-12-01 18:00:55 +01:00
Tokenizer tokenizer ( & settings , this ) ;
2010-10-28 18:01:51 +02:00
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.java " ) ;
tokenizer . simplifyTokenList ( ) ;
// Check..
CheckClass checkClass ( & tokenizer , & settings , this ) ;
checkClass . constructors ( ) ;
}
2010-10-23 10:56:30 +02:00
void uninitJava ( )
{
2010-10-28 18:01:51 +02:00
checkUninitVarJava ( " class A { \n "
" private: int i = 0; \n "
" public: A() { } \n "
" }; " ) ;
2010-10-23 10:56:30 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-04-02 19:29:54 +02:00
2009-02-21 14:35:55 +01:00
void checkNoConstructor ( const char code [ ] )
{
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
settings . _checkCodingStyle = true ;
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 ( ) ;
}
void noConstructor1 ( )
{
// 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
}
void noConstructor2 ( )
{
checkNoConstructor ( " class Fred \n "
" { \n "
" public: \n "
" static void foobar(); \n "
" }; \n "
" \n "
" void Fred::foobar() \n "
" { } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
void noConstructor3 ( )
{
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 ( ) ) ;
}
2009-12-19 17:58:52 +01:00
void noConstructor4 ( )
{
checkNoConstructor ( " class Fred \n "
" { \n "
" public: \n "
" int foobar; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-09 17:50:26 +02:00
void noConstructor5 ( )
{
checkNoConstructor ( " namespace Foo \n "
" { \n "
" int i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-09-02 22:32:15 +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 ( ) ;
}
void memsetOnClass ( )
{
checkNoMemset ( " class A \n "
" { \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 "
" memset(&a, 0, sizeof(A)); \n "
2009-09-02 22:32:15 +02:00
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
void memsetOnStruct ( )
{
checkNoMemset ( " class A \n "
" { \n "
" void g( struct sockaddr_in6& a); \n "
" private: \n "
" std::string b; \n "
" }; \n "
" void f() \n "
" { \n "
" struct sockaddr_in6 fail; \n "
" memset(&fail, 0, sizeof(struct sockaddr_in6)); \n "
" } \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 " ) ;
ASSERT_EQUALS ( " [test.cpp:10]: (error) Using 'memset' on struct that contains a 'std::string' \n " , errout . str ( ) ) ;
}
2009-09-12 15:25:02 +02:00
2010-02-04 19:40:35 +01:00
void memsetVector ( )
{
checkNoMemset ( " struct A \n "
" { std::vector<int> ints; } \n "
" \n "
" void f() \n "
" { \n "
" A a; \n "
" memset(a, 0, sizeof(A)); \n "
" } " ) ;
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 "
" { std::vector< std::vector<int> > ints; } \n "
" \n "
" void f() \n "
" { \n "
" A a; \n "
" memset(a, 0, sizeof(A)); \n "
" } " ) ;
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 "
" { std::vector<int *> ints; } \n "
" \n "
" void f() \n "
" { \n "
" A a; \n "
" memset(a, 0, sizeof(A)); \n "
" } " ) ;
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
void checkThisSubtraction ( const char code [ ] )
{
2010-12-01 18:00:55 +01:00
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
settings . _checkCodingStyle = true ;
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 ( ) ;
}
void this_subtraction ( )
{
checkThisSubtraction ( " ; this-x ; " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (warning) Suspicious pointer subtraction \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 ; " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Suspicious pointer subtraction \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 " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Suspicious pointer subtraction \n "
" [test.cpp:3]: (warning) Suspicious pointer subtraction \n " , errout . str ( ) ) ;
2009-09-12 15:25:02 +02:00
}
2010-01-23 09:19:22 +01:00
2010-08-07 13:08:36 +02:00
void checkConst ( const char code [ ] , const Settings * s = 0 )
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
settings . _checkCodingStyle = true ;
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 ( ) ;
}
void const1 ( )
{
checkConst ( " class Fred { \n "
" int a; \n "
" int getA() { return a; } \n "
" }; \n " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:2]: (information) Technically the member function 'Fred::foo' can be const. \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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) Technically the member function 'Fred::foo' can be const. \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 ( ) ) ;
2010-01-23 21:08:40 +01:00
// functions with a function call can't be const..
checkConst ( " class foo \n "
" { \n "
" public: \n "
" int x; \n "
" void b() { a(); } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
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 ( ) ) ;
2010-02-08 07:25:19 +01:00
}
void const2 ( )
{
// 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) 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 ( ) ) ;
}
void const3 ( )
{
// assignment to function argument pointer can be const
checkConst ( " class Fred { \n "
" int s; \n "
" void foo(int * a) { *a = s; } \n "
" }; \n " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) 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
2010-03-05 17:06:25 +01:00
void const4 ( )
{
checkConst ( " class Fred { \n "
" int a; \n "
" int getA(); \n "
" }; \n "
" int Fred::getA() { return a; } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (information) Technically the member function 'Fred::getA' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
checkConst ( " class Fred { \n "
" const std::string foo(); \n "
" }; \n "
" const std::string Fred::foo() { return " " ; } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:2]: (information) Technically the member function 'Fred::foo' 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 " " ; } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (information) Technically the member function 'Fred::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-05 17:06:25 +01:00
// constructors can't be const..
checkConst ( " class Fred { \n "
" int a; \n "
" public: \n "
" Fred() \n "
" }; \n "
" Fred::Fred() { } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// assignment through |=..
checkConst ( " class Fred { \n "
" int a; \n "
" int setA(); \n "
" }; \n "
" int Fred::setA() { a |= true; } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// functions with a function call 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 "
" int x; \n "
" 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; } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (information) 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; } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (information) 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; } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (information) 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; } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (information) 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; } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:7] -> [test.cpp:3]: (information) Technically the member function 'Fred::foo' can be const. \n "
" [test.cpp:7] -> [test.cpp:4]: (information) 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) { } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:9] -> [test.cpp:3]: (information) Technically the member function 'Fred::foo1' can be const. \n "
" [test.cpp:10] -> [test.cpp:4]: (information) Technically the member function 'Fred::foo2' can be const. \n "
" [test.cpp:11] -> [test.cpp:5]: (information) Technically the member function 'Fred::foo3' can be const. \n "
" [test.cpp:12] -> [test.cpp:6]: (information) Technically the member function 'Fred::foo4' can be const. \n "
" [test.cpp:13] -> [test.cpp:7]: (information) Technically the member function 'Fred::foo5' can be const. \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 "
" }; " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" }; " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:6] -> [test.cpp:4]: (information) 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; } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:7] -> [test.cpp:4]: (information) 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 "
" }; " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) Technically the member function 'Fred::B::getB' can be const. \n "
" [test.cpp:7]: (information) 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 "
" }; " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:4]: (information) Technically the member function 'Fred::B::getB' can be const. \n "
" [test.cpp:9] -> [test.cpp:7]: (information) 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 "
" }; " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:4]: (information) Technically the member function 'Fred::B::getB' can be const. \n "
" [test.cpp:10] -> [test.cpp:7]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:12] -> [test.cpp:4]: (information) Technically the member function 'Fred::B::getB' can be const. \n "
" [test.cpp:11] -> [test.cpp:7]: (information) 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
2010-04-02 22:03:07 +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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) 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<<
void constoperator2 ( )
{
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 ( ) ) ;
}
2010-08-30 17:14:20 +02:00
void constoperator3 ( )
{
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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) Technically the member function 'Fred::operator[]' can be const. \n " , errout . str ( ) ) ;
2010-08-30 17:14:20 +02:00
}
2010-12-29 20:22:06 +01:00
void constoperator4 ( )
{
checkConst ( " struct Fred { \n "
" int array[10]; \n "
" typedef int* (Fred::*UnspecifiedBoolType); \n "
" operator UnspecifiedBoolType() { }; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (information) Technically the member function 'Fred::int' can be const. \n " , errout . str ( ) ) ;
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
}
2010-03-12 18:30:20 +01:00
void const5 ( )
{
// 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 "
" }; " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) Technically the member function 'A::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-12 18:30:20 +01:00
}
2010-03-13 08:06:20 +01:00
void const6 ( )
{
// ticket # 1491
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 "
" }; " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) Technically the member function 'Fred::foo' can be const. \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
}
2010-03-16 07:31:40 +01:00
void const7 ( )
{
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 ( ) ) ;
}
2010-03-23 07:34:34 +01:00
void const8 ( )
{
// 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) Technically the member function 'A::strGetString' can be const. \n " , errout . str ( ) ) ;
2010-03-23 07:34:34 +01:00
}
2010-03-23 07:37:20 +01:00
void const9 ( )
{
// ticket #1515
checkConst ( " class wxThreadInternal { \n "
" public: \n "
" void SetExitCode(wxThread::ExitCode exitcode) { m_exitcode = exitcode; } \n "
" private: \n "
" wxThread::ExitCode m_exitcode; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-03-24 19:31:30 +01: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 "
" } " ) ;
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 "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class A { \n "
" public: \n "
" int foo() { return (x ? x = 0 : x); } \n "
" private: \n "
" int x; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-03-24 19:31:30 +01:00
}
2010-03-26 18:16:33 +01:00
void const11 ( )
{
// ticket #1529
checkConst ( " class A { \n "
" public: \n "
" void set(struct tm time) { m_time = time; } \n "
" private: \n "
" struct tm m_time; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-03-26 19:06:00 +01:00
void const12 ( )
{
// ticket #1525
checkConst ( " class A { \n "
" public: \n "
" int foo() { x = 0; } \n "
" private: \n "
" mutable int x; \n "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) Technically the member function 'A::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-26 19:06:00 +01:00
}
2010-03-26 20:14:31 +01:00
void const13 ( )
{
// 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) Technically the member function 'A::GetVec' can be const. \n "
2010-12-27 08:22:21 +01:00
" [test.cpp:5]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) Technically the member function 'A::GetVec' can be const. \n "
" [test.cpp:5]: (information) Technically the member function 'A::GetPair' can be const. \n " , errout . str ( ) ) ;
2010-03-26 20:14:31 +01:00
}
2010-03-27 14:11:46 +01: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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
2010-12-27 08:22:21 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
" } " ) ;
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 "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class A { \n "
" public: \n "
" const int ** foo() { return &x; } \n "
" private: \n "
" const int * x; \n "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) 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 "
" } " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) Technically the member function 'A::foo' can be const. \n " , errout . str ( ) ) ;
2010-03-27 14:11:46 +01:00
}
2010-03-28 15:56:13 +02:00
void const15 ( )
{
checkConst ( " class Fred { \n "
" unsigned long long int a; \n "
" unsigned long long int getA() { return a; } \n "
" }; \n " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) 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 ( ) ) ;
// functions with a function call can't be const..
checkConst ( " class foo \n "
" { \n "
" public: \n "
" unsigned long long int x; \n "
" void b() { a(); } \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 ( ) ) ;
}
2010-04-01 16:59:35 +02:00
void const16 ( )
{
// ticket #1551
checkConst ( " class Fred { \n "
" int a; \n "
" void set(int i) { Fred::a = i; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-04-01 17:01:52 +02:00
void const17 ( )
{
// 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 ( ) ) ;
}
2010-04-02 08:02:47 +02:00
void const18 ( )
{
// ticket #1563
checkConst ( " class Fred { \n "
" static int x; \n "
" public: \n "
" void set(int i) { x = i; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-04-18 07:53:39 +02:00
void const19 ( )
{
// 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 ( ) ) ;
}
2010-04-18 15:40:31 +02:00
void const20 ( )
{
// 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) Technically the member function 'Fred::get' can be const. \n " , errout . str ( ) ) ;
2010-04-18 15:40:31 +02:00
}
2010-05-16 20:26:32 +02:00
void const21 ( )
{
// 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 ( ) ) ;
}
2010-05-20 06:52:59 +02:00
void const22 ( )
{
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 ( ) ) ;
}
2010-05-20 17:45:10 +02:00
void const23 ( )
{
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 ( ) ) ;
}
2010-05-25 06:55:49 +02:00
void const24 ( )
{
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
void const25 ( ) // ticket #1724
{
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 "
) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
) ;
2010-12-27 08:22:21 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) 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 "
) ;
2010-12-26 22:34:00 +01:00
TODO_ASSERT_EQUALS ( " [test.cpp:4]: (information) Technically the member function 'A::strGetSize' can be const. \n " , errout . str ( ) ) ;
2010-06-03 12:51:42 +02:00
}
2010-07-13 08:01:57 +02:00
void const26 ( ) // ticket #1847
{
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 ( ) ) ;
}
2010-08-09 17:54:16 +02:00
void const27 ( ) // ticket #1882
{
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 "
) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:9] -> [test.cpp:4]: (information) Technically the member function 'A::dGetValue' can be const. \n " , errout . str ( ) ) ;
2010-08-09 17:54:16 +02:00
}
2010-07-19 13:16:11 +02:00
void const28 ( ) // ticket #1883
{
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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (information) Technically the member function 'AA::vSetXPos' can be const. \n " , errout . str ( ) ) ;
2010-07-20 09:43:27 +02:00
2010-07-19 13:16:11 +02:00
}
2010-08-09 17:54:16 +02:00
void const29 ( ) // ticket #1922
2010-07-19 08:40:46 +02:00
{
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 ( ) ) ;
}
void const30 ( )
{
// 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 " ) ;
2010-12-27 08:22:21 +01:00
ASSERT_EQUALS ( " [test.cpp:7]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:11]: (information) Technically the member function 'Derived::getA' can be const. \n "
" [test.cpp:14]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:8]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:10]: (information) 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
}
2010-08-14 08:16:53 +02:00
void const31 ( )
{
checkConst ( " namespace std { } \n "
" class Fred { \n "
" public: \n "
" int a; \n "
" int get() { return a; } \n "
" }; \n " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:5]: (information) Technically the member function 'Fred::get' can be const. \n " , errout . str ( ) ) ;
2010-08-14 08:16:53 +02:00
}
2010-08-15 08:30:21 +02:00
void const32 ( )
{
checkConst ( " class Fred { \n "
" public: \n "
" std::string a[10]; \n "
" void seta() { a[0] = \" \" ; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-20 07:28:31 +02:00
void const33 ( )
{
checkConst ( " class derived : public base { \n "
" public: \n "
" void f(){} \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-20 19:47:41 +02:00
void const34 ( ) // ticket #1964
{
checkConst ( " class Bar { \n "
" void init(Foo * foo) { \n "
" foo.bar = this; \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-31 17:57:42 +02:00
void const35 ( ) // ticket #2001
{
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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:12]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:10] -> [test.cpp:6]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:12] -> [test.cpp:6]: (information) 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 " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-26 22:34:00 +01:00
TODO_ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:6]: (information) Technically the member function 'N::Base::getResourceName' can be const. \n " , errout . str ( ) ) ;
2010-08-31 17:57:42 +02:00
}
2010-09-01 06:18:09 +02:00
void const36 ( ) // ticket #2003
{
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 "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-10-12 07:57:09 +02:00
void const37 ( ) // ticket #2081 and #2085
{
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 "
" } \n " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:5]: (information) 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 "
" } \n " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:9]: (information) Technically the member function 'Fred::isValid' can be const. \n " , errout . str ( ) ) ;
2010-10-12 07:57:09 +02:00
}
2010-10-27 19:25:34 +02:00
void const38 ( ) // ticket #2135
{
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 ( ) ) ;
}
2010-11-06 20:27:12 +01:00
void const39 ( )
{
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 ( ) ) ;
}
2010-11-25 07:15:33 +01:00
void const40 ( ) // ticket #2228
{
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 "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-11-30 19:40:32 +01:00
void const41 ( ) // ticket #2255
{
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 ( ) ) ;
}
2010-12-07 19:42:30 +01:00
void const42 ( ) // ticket #2282
{
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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:7] -> [test.cpp:5]: (information) Technically the member function 'Fred::f' can be const. \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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:9] -> [test.cpp:7]: (information) Technically the member function 'Fred::f' can be const. \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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:10] -> [test.cpp:8]: (information) Technically the member function 'NS::Fred::f' can be const. \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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:8]: (information) Technically the member function 'NS::Fred::f' can be const. \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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:8]: (information) Technically the member function 'Foo::Fred::f' can be const. \n " , errout . str ( ) ) ;
2010-12-07 19:42:30 +01:00
}
2010-12-30 01:29:09 +01:00
void const43 ( ) // ticket 2377
{
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
}
2010-12-30 22:57:43 +01:00
void assigningPointerToPointerIsNotAConstOperation ( )
{
checkConst ( " struct s \n "
" { \n "
" int** v; \n "
" void f() \n "
" { \n "
" v = 0; \n "
" } \n "
" }; \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-01-24 13:33:30 +01:00
// increment/decrement => not const
void constincdec ( )
{
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 ( ) ) ;
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 ( ) ) ;
2010-01-24 13:33:30 +01:00
}
2010-01-25 21:40:57 +01:00
// return pointer/reference => not const
void constReturnReference ( )
{
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)
void constDelete ( )
{
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
void constLPVOID ( )
{
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
void constFunc ( )
{
checkConst ( " class Fred { \n "
" void f() const { }; \n "
" void a() { f(); }; \n "
" }; \n " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (information) Technically the member function 'Fred::a' can be const. \n " , errout . str ( ) ) ;
2010-04-19 21:18:53 +02:00
// ticket #1593
checkConst ( " #include <vector> \n "
" class A \n "
" { \n "
" std::vector<int> m_v; \n "
" public: \n "
" A(){} \n "
" unsigned int GetVecSize() {return m_v.size();} \n "
" } " ) ;
2010-12-26 22:34:00 +01:00
TODO_ASSERT_EQUALS ( " [test.cpp:7]: (information) Technically the member function 'A::GetVecSize' can be const. \n " , errout . str ( ) ) ;
2010-04-19 21:18:53 +02:00
}
2010-07-18 10:18:41 +02:00
void constVirtualFunc ( )
{
// 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:6]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:8] -> [test.cpp:6]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:9]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:11] -> [test.cpp:9]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:5]: (information) Technically the member function 'A::func' can be const. \n "
" [test.cpp:11]: (information) Technically the member function 'B::func' can be const. \n "
" [test.cpp:17]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:7] -> [test.cpp:5]: (information) Technically the member function 'A::func' can be const. \n "
" [test.cpp:14] -> [test.cpp:12]: (information) Technically the member function 'B::func' can be const. \n "
" [test.cpp:21] -> [test.cpp:19]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:5]: (information) Technically the member function 'X::getX' can be const. \n "
" [test.cpp:11]: (information) Technically the member function 'Y::getY' can be const. \n "
" [test.cpp:17]: (information) 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 " ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:7] -> [test.cpp:5]: (information) Technically the member function 'X::getX' can be const. \n "
" [test.cpp:14] -> [test.cpp:12]: (information) Technically the member function 'Y::getY' can be const. \n "
" [test.cpp:21] -> [test.cpp:19]: (information) 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
void constIfCfg ( )
{
const char code [ ] = " class foo { \n "
" void f() { } \n "
" }; " ;
Settings settings ;
settings . _checkCodingStyle = true ;
settings . ifcfg = false ;
checkConst ( code , & settings ) ;
2010-12-26 22:34:00 +01:00
ASSERT_EQUALS ( " [test.cpp:2]: (information) Technically the member function 'foo::f' can be const. \n " , errout . str ( ) ) ;
2010-08-07 13:08:36 +02:00
settings . ifcfg = true ;
checkConst ( code , & settings ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-07 16:08:44 +02:00
void constFriend ( ) // ticket #1921
{
const char code [ ] = " class foo { \n "
" friend void f() { } \n "
" }; " ;
checkConst ( code ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-16 18:55:39 +02:00
2010-10-24 16:43:10 +02:00
void constUnion ( ) // ticket #2111
{
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 "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-16 18:55:39 +02:00
void symboldatabase1 ( )
{
checkConst ( " namespace foo { \n "
" class bar; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class foo : public bar < int, int> { \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-18 22:42:04 +02:00
void symboldatabase2 ( )
{
checkConst ( " class foo { \n "
" public slots : \n "
" foo() { } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " class foo { \n "
" class bar; \n "
" foo() { } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-31 17:51:10 +02:00
void symboldatabase3 ( )
{
checkConst ( " typedef void (func_type)(); \n "
" struct A { \n "
" friend func_type f : 2; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-11-03 20:33:07 +01:00
void symboldatabase4 ( )
{
checkConst ( " static void function_declaration_before(void) __attribute__((__used__)); \n "
" static void function_declaration_before(void) {} \n "
" static void function_declaration_after(void) {} \n "
" static void function_declaration_after(void) __attribute__((__used__)); \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " main(int argc, char *argv[]) { } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " namespace boost { \n "
" std::locale generate_locale() \n "
" { \n "
" return std::locale(); \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkConst ( " namespace X { \n "
" static void function_declaration_before(void) __attribute__((__used__)); \n "
" static void function_declaration_before(void) {} \n "
" static void function_declaration_after(void) {} \n "
" static void function_declaration_after(void) __attribute__((__used__)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-11-04 06:58:37 +01:00
checkConst ( " testing::testing() \n "
" { \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-11-03 20:33:07 +01:00
}
2010-11-08 19:47:19 +01:00
void symboldatabase5 ( )
{
// ticket #2178 - segmentation fault
checkConst ( " int CL_INLINE_DECL(integer_decode_float) (int x) { \n "
" return (sign ? cl_I() : 0); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-11-23 07:31:15 +01:00
void symboldatabase6 ( )
{
// ticket #2221 - segmentation fault
checkConst ( " template<int i> class X { }; \n "
" X< 1>2 > x1; \n "
" X<(1>2)> x2; \n "
" template<class T> class Y { }; \n "
" Y<X<1>> x3; \n "
" Y<X<6>>1>> x4; \n "
" Y<X<(6>>1)>> x5; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-11-25 07:43:39 +01:00
void symboldatabase7 ( )
{
// ticket #2230 - segmentation fault
checkConst ( " template<template<class> class E,class D> class C : E<D> \n "
" { \n "
" public: \n "
" int f(); \n "
" }; \n "
" class E : C<D,int> \n "
" { \n "
" public: \n "
" int f() { return C< ::D,int>::f(); } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-11-30 19:52:42 +01:00
void symboldatabase8 ( )
{
// ticket #2252 - segmentation fault
checkConst ( " struct PaletteColorSpaceHolder: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>, \n "
" PaletteColorSpaceHolder> \n "
" { \n "
" uno::Reference<rendering::XColorSpace> operator()() \n "
" { \n "
" return vcl::unotools::createStandardColorSpace(); \n "
" } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-12-30 07:47:05 +01:00
2008-12-18 22:28:57 +01:00
} ;
2009-01-05 16:49:57 +01:00
REGISTER_TEST ( TestClass )