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
2023-01-28 10:16:34 +01:00
* Copyright ( C ) 2007 - 2023 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 "checkclass.h"
2022-01-27 19:03:20 +01:00
# include "errortypes.h"
2017-05-27 04:33:47 +02:00
# include "platform.h"
# include "settings.h"
2023-01-27 08:18:32 +01:00
# include "fixture.h"
2017-05-27 04:33:47 +02:00
# include "tokenize.h"
# include <map>
2022-09-16 07:15:49 +02:00
# include <sstream> // IWYU pragma: keep
2022-01-27 19:03:20 +01:00
# include <string>
# include <utility>
2017-05-27 04:33:47 +02:00
# include <vector>
2008-12-18 22:28:57 +01:00
2022-01-27 19:03:20 +01:00
# include <simplecpp.h>
2011-10-13 20:53:06 +02:00
class TestUnusedPrivateFunction : public TestFixture {
2008-12-18 22:28:57 +01:00
public :
2021-08-07 20:51:18 +02:00
TestUnusedPrivateFunction ( ) : TestFixture ( " TestUnusedPrivateFunction " ) { }
2008-12-18 22:28:57 +01:00
private :
2023-05-02 15:54:19 +02:00
const Settings settings = settingsBuilder ( ) . severity ( Severity : : style ) . build ( ) ;
2015-10-07 18:33:57 +02:00
2022-02-10 23:02:24 +01:00
void run ( ) override {
2009-01-05 16:49:57 +01:00
TEST_CASE ( test1 ) ;
2009-02-25 19:03:17 +01:00
TEST_CASE ( test2 ) ;
2009-03-02 18:16:02 +01:00
TEST_CASE ( test3 ) ;
2009-03-02 21:40:24 +01:00
TEST_CASE ( test4 ) ;
2009-09-16 23:04:13 +02:00
TEST_CASE ( test5 ) ;
2011-02-22 12:47:28 +01:00
TEST_CASE ( test6 ) ; // ticket #2602
2022-08-07 20:06:32 +02:00
TEST_CASE ( test7 ) ; // ticket #9282
2008-12-18 22:28:57 +01:00
// [ 2236547 ] False positive --style unused function, called via pointer
2010-04-08 19:06:54 +02:00
TEST_CASE ( func_pointer1 ) ;
TEST_CASE ( func_pointer2 ) ;
2010-08-15 07:44:08 +02:00
TEST_CASE ( func_pointer3 ) ;
2011-06-29 13:19:34 +02:00
TEST_CASE ( func_pointer4 ) ; // ticket #2807
2011-12-14 21:11:40 +01:00
TEST_CASE ( func_pointer5 ) ; // ticket #2233
2014-01-01 18:36:51 +01:00
TEST_CASE ( func_pointer6 ) ; // ticket #4787
2022-03-14 19:15:48 +01:00
TEST_CASE ( func_pointer7 ) ; // ticket #10516
2009-04-14 21:46:13 +02:00
TEST_CASE ( ctor ) ;
2013-08-26 16:41:23 +02:00
TEST_CASE ( ctor2 ) ;
2009-07-07 08:30:23 +02:00
TEST_CASE ( classInClass ) ;
2009-07-07 08:55:14 +02:00
TEST_CASE ( sameFunctionNames ) ;
2009-07-12 14:23:01 +02:00
TEST_CASE ( incompleteImplementation ) ;
2010-08-26 22:05:45 +02:00
TEST_CASE ( derivedClass ) ; // skip warning for derived classes. It might be a virtual function.
2010-09-07 18:37:43 +02:00
2011-01-22 13:00:03 +01:00
TEST_CASE ( friendClass ) ;
2012-04-09 11:19:19 +02:00
TEST_CASE ( borland1 ) ; // skip FP when using __property
TEST_CASE ( borland2 ) ; // skip FP when using __published
2010-09-30 21:22:49 +02:00
// No false positives when there are "unused" templates that are removed in the simplified token list
TEST_CASE ( template1 ) ;
2011-01-16 12:16:31 +01:00
// #2407 - FP when called from operator()
TEST_CASE ( fp_operator ) ;
2011-01-19 01:58:44 +01:00
TEST_CASE ( testDoesNotIdentifyMethodAsFirstFunctionArgument ) ; // #2480
TEST_CASE ( testDoesNotIdentifyMethodAsMiddleFunctionArgument ) ;
TEST_CASE ( testDoesNotIdentifyMethodAsLastFunctionArgument ) ;
2011-02-11 14:00:41 +01:00
TEST_CASE ( multiFile ) ;
2011-02-15 01:50:13 +01:00
TEST_CASE ( unknownBaseTemplate ) ; // ticket #2580
2020-12-05 08:00:31 +01:00
TEST_CASE ( hierarchy_loop ) ; // ticket 5590
2014-08-26 11:29:26 +02:00
TEST_CASE ( staticVariable ) ; //ticket #5566
2018-12-29 11:19:53 +01:00
TEST_CASE ( templateSimplification ) ; //ticket #6183
2022-11-10 20:58:39 +01:00
TEST_CASE ( maybeUnused ) ;
2008-12-18 22:28:57 +01:00
}
2023-03-03 18:36:27 +01:00
void check ( const char code [ ] , cppcheck : : Platform : : Type platform = cppcheck : : Platform : : Type : : Native ) {
2010-12-01 18:00:55 +01:00
// Clear the error buffer..
errout . str ( " " ) ;
2023-05-02 15:54:19 +02:00
const Settings settings1 = settingsBuilder ( settings ) . platform ( platform ) . build ( ) ;
2010-12-01 18:00:55 +01:00
2017-05-18 21:52:31 +02:00
// Raw tokens..
2018-04-09 09:41:24 +02:00
std : : vector < std : : string > files ( 1 , " test.cpp " ) ;
2017-05-18 21:52:31 +02:00
std : : istringstream istr ( code ) ;
const simplecpp : : TokenList tokens1 ( istr , files , files [ 0 ] ) ;
// Preprocess..
simplecpp : : TokenList tokens2 ( files ) ;
std : : map < std : : string , simplecpp : : TokenList * > filedata ;
simplecpp : : preprocess ( tokens2 , tokens1 , files , filedata , simplecpp : : DUI ( ) ) ;
2008-12-18 22:28:57 +01:00
// Tokenize..
2023-05-02 15:54:19 +02:00
Tokenizer tokenizer ( & settings1 , this ) ;
2020-05-16 18:44:17 +02:00
tokenizer . createTokens ( std : : move ( tokens2 ) ) ;
2017-05-18 21:52:31 +02:00
tokenizer . simplifyTokens1 ( " " ) ;
2008-12-18 22:28:57 +01:00
2012-07-09 20:40:49 +02:00
// Check for unused private functions..
2023-05-02 15:54:19 +02:00
CheckClass checkClass ( & tokenizer , & settings1 , this ) ;
2008-12-20 09:48:52 +01:00
checkClass . privateFunctions ( ) ;
2008-12-18 22:28:57 +01:00
}
2014-11-20 14:20:09 +01:00
void test1 ( ) {
2009-01-05 16:49:57 +01:00
check ( " class Fred \n "
" { \n "
" private: \n "
" unsigned int f(); \n "
" public: \n "
" Fred(); \n "
" }; \n "
" \n "
" Fred::Fred() \n "
" { } \n "
" \n "
" unsigned int Fred::f() \n "
2013-03-20 15:36:16 +01:00
" { } " ) ;
2009-01-05 16:49:57 +01:00
2012-07-09 20:36:28 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) Unused private function: 'Fred::f' \n " , errout . str ( ) ) ;
2009-06-20 22:13:19 +02:00
2017-05-18 21:52:31 +02:00
check ( " #line 1 \" p.h \" \n "
2009-06-20 22:13:19 +02:00
" class Fred \n "
" { \n "
" private: \n "
" unsigned int f(); \n "
" public: \n "
" Fred(); \n "
" }; \n "
" \n "
2017-05-18 21:52:31 +02:00
" #line 1 \" p.cpp \" \n "
2009-06-20 22:13:19 +02:00
" Fred::Fred() \n "
" { } \n "
" \n "
" unsigned int Fred::f() \n "
2013-03-20 15:36:16 +01:00
" { } " ) ;
2009-06-20 22:13:19 +02:00
2012-07-09 20:36:28 +02:00
ASSERT_EQUALS ( " [p.h:4]: (style) Unused private function: 'Fred::f' \n " , errout . str ( ) ) ;
2009-06-20 22:13:19 +02:00
2017-05-18 21:52:31 +02:00
check ( " #line 1 \" p.h \" \n "
2009-06-20 22:13:19 +02:00
" class Fred \n "
" { \n "
" private: \n "
" void f(); \n "
" }; \n "
" \n "
" \n "
2017-05-18 21:52:31 +02:00
" #line 1 \" p.cpp \" \n "
2009-06-20 22:13:19 +02:00
" \n "
" void Fred::f() \n "
" { \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-09 20:36:28 +02:00
ASSERT_EQUALS ( " [p.h:4]: (style) Unused private function: 'Fred::f' \n " , errout . str ( ) ) ;
2009-06-20 22:13:19 +02:00
// Don't warn about include files which implementation we don't see
2017-05-18 21:52:31 +02:00
check ( " #line 1 \" p.h \" \n "
2009-06-20 22:13:19 +02:00
" class Fred \n "
" { \n "
" private: \n "
" void f(); \n "
" void g() {} \n "
" }; \n "
" \n "
2017-05-18 21:52:31 +02:00
" #line 1 \" p.cpp \" \n "
2009-06-20 22:13:19 +02:00
" \n "
" int main() \n "
" { \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2009-06-20 22:13:19 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2014-11-20 14:20:09 +01:00
void test2 ( ) {
2009-02-25 19:03:17 +01:00
check ( " class A { \n "
" public: \n "
" A(); \n "
" \n "
" void a() const \n "
" { b(); } \n "
" private: \n "
" void b( ) const \n "
" { } \n "
" }; \n "
" \n "
" A::A() \n "
2013-03-20 15:36:16 +01:00
" { } " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-02-25 19:03:17 +01:00
}
2014-11-20 14:20:09 +01:00
void test3 ( ) {
2009-03-02 18:16:02 +01:00
check ( " class A { \n "
" public: \n "
" A() { } \n "
" ~A(); \n "
" private: \n "
" void B() { } \n "
" }; \n "
" \n "
" A::~A() \n "
2013-03-20 15:36:16 +01:00
" { B(); } " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-03-02 18:16:02 +01:00
}
2014-11-20 14:20:09 +01:00
void test4 ( ) {
2009-03-02 21:40:24 +01:00
check ( " class A { \n "
" public: \n "
" A(); \n "
" private: \n "
" bool _owner; \n "
" void b() { } \n "
" }; \n "
" \n "
" A::A() : _owner(false) \n "
2013-03-20 15:36:16 +01:00
" { b(); } " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-03-02 21:40:24 +01:00
}
2014-11-20 14:20:09 +01:00
void test5 ( ) {
2009-09-16 23:04:13 +02:00
check ( " class A { \n "
" private: \n "
" A() : lock(new Lock()) \n "
" { } \n "
" Lock *lock; \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2009-09-16 23:04:13 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-02-25 19:03:17 +01:00
2014-11-20 14:20:09 +01:00
void test6 ( ) { // ticket #2602 segmentation fault
2011-02-22 12:47:28 +01:00
check ( " class A { \n "
" A& operator=(const A&); \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2011-02-22 12:47:28 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2022-08-07 20:06:32 +02:00
void test7 ( ) { // ticket #9282
check ( " class C { \n "
" double f1() const noexcept, f2(double) const noexcept; \n "
" void f3() const noexcept; \n "
" }; \n "
" double C::f1() const noexcept { f3(); } \n "
" void C::f3() const noexcept {} \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2008-12-18 22:28:57 +01:00
2014-11-20 14:20:09 +01:00
void func_pointer1 ( ) {
2009-01-05 16:49:57 +01:00
check ( " class Fred \n "
" { \n "
" private: \n "
" typedef void (*testfp)(); \n "
" \n "
" testfp get() \n "
" { \n "
" return test; \n "
" } \n "
" \n "
" static void test() \n "
" { } \n "
" \n "
" public: \n "
" Fred(); \n "
" }; \n "
" \n "
" Fred::Fred() \n "
2013-03-20 15:36:16 +01:00
" {} " ) ;
2009-01-05 16:49:57 +01:00
2012-07-09 20:36:28 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (style) Unused private function: 'Fred::get' \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2010-04-08 19:06:54 +02:00
2014-11-20 14:20:09 +01:00
void func_pointer2 ( ) {
2010-04-08 19:06:54 +02:00
check ( " class UnusedPrivateFunctionMemberPointer \n "
" { \n "
" public: \n "
" UnusedPrivateFunctionMemberPointer() \n "
" : mObserver(this, &UnusedPrivateFunctionMemberPointer::callback) \n "
" {} \n "
" \n "
" private: \n "
" void callback(const& unsigned) const {} \n "
" \n "
" Observer<UnusedPrivateFunctionMemberPointer, unsigned> mObserver; \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2010-04-08 19:06:54 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void func_pointer3 ( ) {
2010-08-15 07:44:08 +02:00
check ( " class c1 \n "
" { \n "
" public: \n "
" c1() \n "
" { sigc::mem_fun(this, &c1::f1); } \n "
" \n "
" private: \n "
" void f1() const {} \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2010-08-15 07:44:08 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-04-08 19:06:54 +02:00
2014-11-20 14:20:09 +01:00
void func_pointer4 ( ) { // ticket #2807
2011-06-29 13:19:34 +02:00
check ( " class myclass { \n "
" public: \n "
" myclass(); \n "
" private: \n "
" static void f(); \n "
" void (*fptr)(); \n "
" }; \n "
" myclass::myclass() { fptr = &f; } \n "
2013-03-20 15:36:16 +01:00
" void myclass::f() {} " ) ;
2011-06-29 13:19:34 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void func_pointer5 ( ) {
2011-12-14 21:11:40 +01:00
check ( " class A { \n "
" public: \n "
" A() { f = A::func; } \n "
" void (*f)(); \n "
" private: \n "
" static void func() { } \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2011-12-14 21:11:40 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void func_pointer6 ( ) { // #4787
2014-01-01 18:36:51 +01:00
check ( " class Test { \n "
" private: \n "
" static void a(const char* p) { } \n "
" public: \n "
" void test(void* f = a) { \n "
" f( \" test \" ); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2022-03-14 19:15:48 +01:00
void func_pointer7 ( ) { // #10516
check ( " class C { \n "
" static void f() {} \n "
" static constexpr void(*p)() = f; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " class C { \n "
" static void f() {} \n "
" static constexpr void(*p)() = &f; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " class C { \n "
" static void f() {} \n "
" static constexpr void(*p)() = C::f; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " class C { \n "
" static void f() {} \n "
" static constexpr void(*p)() = &C::f; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-12-14 21:11:40 +01:00
2014-11-20 14:20:09 +01:00
void ctor ( ) {
2009-04-14 21:46:13 +02:00
check ( " class PrivateCtor \n "
" { \n "
" private: \n "
" PrivateCtor(int threadNum) : \n "
" numOfThreads(threadNum) \n "
" { \n "
" } \n "
" \n "
" int numOfThreads; \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2009-04-14 21:46:13 +02:00
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-04-14 21:46:13 +02:00
}
2014-11-20 14:20:09 +01:00
void ctor2 ( ) {
2013-08-26 16:41:23 +02:00
check ( " struct State { \n "
" State(double const totalWeighting= TotalWeighting()) : \n "
" totalWeighting_(totalWeighting) {} \n "
" private: \n "
" double TotalWeighting() { return 123.0; } \n " // called from constructor
" public: \n "
" double totalWeighting_; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2008-12-18 22:28:57 +01:00
2014-11-20 14:20:09 +01:00
void classInClass ( ) {
2009-07-07 08:30:23 +02:00
check ( " class A \n "
" { \n "
" public: \n "
" \n "
" class B \n "
" { \n "
" private: \n "
" }; \n "
2013-02-16 10:51:08 +01:00
" private: \n "
2009-07-07 08:30:23 +02:00
" static void f() \n "
" { } \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2013-02-16 10:51:08 +01:00
ASSERT_EQUALS ( " [test.cpp:10]: (style) Unused private function: 'A::f' \n " , errout . str ( ) ) ;
2009-09-25 20:42:22 +02:00
check ( " class A \n "
" { \n "
" public: \n "
" A() \n "
" { } \n "
" \n "
" private: \n "
" void f() \n "
" { } \n "
" \n "
" class B \n "
" { \n "
" public: \n "
" B(A *a) \n "
" { a->f(); } \n "
" }; \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2016-05-16 20:52:50 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " class A { \n " // #6968 - outer definition
" public: \n "
" class B; \n "
" private: \n "
" void f() {} \n "
" } \n "
" class A::B { "
" B() { A a; a.f(); } \n "
2021-02-20 12:58:42 +01:00
" } " ) ;
2009-09-25 20:42:22 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-07-07 08:30:23 +02:00
}
2009-07-07 08:55:14 +02:00
2014-11-20 14:20:09 +01:00
void sameFunctionNames ( ) {
2009-07-07 08:55:14 +02:00
check ( " class A \n "
" { \n "
" public: \n "
" void a() \n "
" { \n "
" f(1); \n "
" } \n "
" \n "
" private: \n "
" void f() { } \n "
" void f(int) { } \n "
" }; " ) ;
2016-05-16 10:55:22 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-07-07 08:55:14 +02:00
}
2009-07-12 14:23:01 +02:00
2014-11-20 14:20:09 +01:00
void incompleteImplementation ( ) {
2009-07-12 14:23:01 +02:00
// The implementation for "A::a" is missing - so don't check if
// "A::b" is used or not
check ( " #file \" test.h \" \n "
" class A \n "
" { \n "
" public: \n "
2015-02-24 06:11:31 +01:00
" A(); \n "
2009-07-12 14:23:01 +02:00
" void a(); \n "
" private: \n "
" void b(); \n "
" }; \n "
" #endfile \n "
" A::A() { } \n "
2013-03-20 15:36:16 +01:00
" void A::b() { } " ) ;
2009-07-12 14:23:01 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-26 22:05:45 +02:00
2014-11-20 14:20:09 +01:00
void derivedClass ( ) {
2011-12-14 21:11:40 +01:00
// skip warning in derived classes in case the base class is invisible
2010-08-26 22:05:45 +02:00
check ( " class derived : public base \n "
" { \n "
" public: \n "
" derived() : base() { } \n "
" private: \n "
" void f(); \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2010-08-26 22:05:45 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-12-14 21:11:40 +01:00
check ( " class base { \n "
" public: \n "
" virtual void foo(); \n "
" void bar(); \n "
" }; \n "
" class derived : public base { \n "
" private: \n "
" void foo() {} \n " // Skip for overrides of virtual functions of base
2013-01-16 15:37:07 +01:00
" void bar() {} \n " // Don't skip if no function is overridden
2011-12-14 21:11:40 +01:00
" }; " ) ;
2012-07-09 20:36:28 +02:00
ASSERT_EQUALS ( " [test.cpp:9]: (style) Unused private function: 'derived::bar' \n " , errout . str ( ) ) ;
2012-02-24 20:45:56 +01:00
check ( " class Base { \n "
" private: \n "
" virtual void func() = 0; \n "
" public: \n "
" void public_func() { \n "
" func(); \n "
" }; \n "
" }; \n "
" \n "
" class Derived1: public Base { \n "
" private: \n "
" void func() {} \n "
" }; \n "
" class Derived2: public Derived1 { \n "
" private: \n "
" void func() {} \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2016-05-21 20:07:35 +02:00
check ( " class Base { \n "
" public: \n "
" void dostuff() { \n "
" f(); \n "
" } \n "
" \n "
" private: \n "
" virtual Base* f() = 0; \n "
" }; \n "
" \n "
" class Derived : public Base { \n "
" private: \n "
" Derived* f() { \n "
" return 0; \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-08-26 22:05:45 +02:00
}
2010-09-07 18:37:43 +02:00
2014-11-20 14:20:09 +01:00
void friendClass ( ) {
2011-01-22 13:00:03 +01:00
// ticket #2459 - friend class
check ( " class Foo { \n "
2012-02-24 20:45:56 +01:00
" private: \n "
" friend Bar; \n " // Unknown friend class
" void f() { } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-02-16 10:51:08 +01:00
check ( " struct Bar { \n "
" void g() { f(); } \n " // Friend class seen, but f not seen
" }; \n "
" class Foo { \n "
" private: \n "
" friend Bar; \n "
" void f(); \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-02-24 20:45:56 +01:00
check ( " struct Bar { \n "
" void g() { f(); } \n " // Friend class seen, but f() used in it
" }; \n "
" class Foo { \n "
2011-01-22 13:00:03 +01:00
" private: \n "
" friend Bar; \n "
" void f() { } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-02-24 20:45:56 +01:00
check ( " class Bar { \n " // Friend class seen, f() not used in it
" }; \n "
" class Foo { \n "
" friend Bar; \n "
" void f() { } \n "
" }; " ) ;
2012-07-09 20:36:28 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (style) Unused private function: 'Foo::f' \n " , errout . str ( ) ) ;
2022-04-13 14:49:28 +02:00
check ( " struct F; \n " // #10265
" struct S { \n "
" int i{}; \n "
" friend struct F; \n "
" private: \n "
" int f() const { return i; } \n "
" }; \n "
" struct F { \n "
" bool operator()(const S& lhs, const S& rhs) const { \n "
" return lhs.f() < rhs.f(); \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-01-22 13:00:03 +01:00
}
2014-11-20 14:20:09 +01:00
void borland1 ( ) {
2010-09-07 18:37:43 +02:00
// ticket #2034 - Borland C++ __property
check ( " class Foo { \n "
" private: \n "
" int getx() { \n "
" return 123; \n "
" } \n "
" public: \n "
" Foo() { } \n "
" __property int x = {read=getx} \n "
2023-03-03 18:36:27 +01:00
" }; " , cppcheck : : Platform : : Type : : Win32A ) ;
2010-09-07 18:37:43 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-09-30 21:22:49 +02:00
2014-11-20 14:20:09 +01:00
void borland2 ( ) {
2012-04-09 11:19:19 +02:00
// ticket #3661 - Borland C++ __published
check ( " class Foo { \n "
" __published: \n "
" int getx() { \n "
" return 123; \n "
" } \n "
" public: \n "
" Foo() { } \n "
2023-03-03 18:36:27 +01:00
" }; " , cppcheck : : Platform : : Type : : Win32A ) ;
2012-04-09 11:19:19 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void template1 ( ) {
2010-09-30 21:22:49 +02:00
// ticket #2067 - Template methods do not "use" private ones
check ( " class A { \n "
" public: \n "
" template <class T> \n "
" T getVal() const; \n "
" \n "
" private: \n "
" int internalGetVal() const { return 8000; } \n "
" }; \n "
" \n "
" template <class T> \n "
" T A::getVal() const { \n "
" return internalGetVal(); \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2010-09-30 21:22:49 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-01-16 12:16:31 +01:00
2014-11-20 14:20:09 +01:00
void fp_operator ( ) {
2011-01-16 12:16:31 +01:00
// #2407 - FP when function is called from operator()
check ( " class Fred \n "
" { \n "
" public: \n "
" void operator()(int x) { \n "
" startListening(); \n "
" } \n "
" \n "
" private: \n "
" void startListening() { \n "
" } \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2011-01-16 12:16:31 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " class Fred \n "
" { \n "
" public: \n "
" void operator()(int x) { \n "
" } \n "
" \n "
" private: \n "
" void startListening() { \n "
" } \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2012-07-09 20:36:28 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (style) Unused private function: 'Fred::startListening' \n " , errout . str ( ) ) ;
2014-03-23 10:06:14 +01:00
// #5059
check ( " class Fred { \n "
" void* operator new(size_t obj_size, size_t buf_size) {} \n "
" }; " ) ;
TODO_ASSERT_EQUALS ( " [test.cpp:2]: (style) Unused private function: 'Fred::operatornew' \n " , " " , errout . str ( ) ) ; // No message for operators - we currently cannot check their usage
check ( " class Fred { \n "
" void* operator new(size_t obj_size, size_t buf_size) {} \n "
" public: \n "
" void* foo() { return new(size) Fred(); } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-01-16 12:16:31 +01:00
}
2011-01-18 11:50:22 +01:00
2014-11-20 14:20:09 +01:00
void testDoesNotIdentifyMethodAsFirstFunctionArgument ( ) {
2012-07-07 20:21:08 +02:00
check ( " void callback(void (*func)(int), int arg) "
2011-01-18 11:50:22 +01:00
" { "
" (*func)(arg); "
" } "
" class MountOperation "
" { "
" static void Completed(int i); "
" public: "
" MountOperation(int i); "
" }; "
" void MountOperation::Completed(int i) "
" { "
" std::cerr << i << std::endl; "
" } "
" MountOperation::MountOperation(int i) "
" { "
" callback(MountOperation::Completed, i); "
" } "
" int main(void) "
" { "
" MountOperation aExample(10); "
" } "
2021-08-07 20:51:18 +02:00
) ;
2011-01-19 01:58:44 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void testDoesNotIdentifyMethodAsMiddleFunctionArgument ( ) {
2012-07-07 20:21:08 +02:00
check ( " void callback(char, void (*func)(int), int arg) "
2011-01-19 01:58:44 +01:00
" { "
" (*func)(arg); "
" } "
" class MountOperation "
" { "
" static void Completed(int i); "
" public: "
" MountOperation(int i); "
" }; "
" void MountOperation::Completed(int i) "
" { "
" std::cerr << i << std::endl; "
" } "
" MountOperation::MountOperation(int i) "
" { "
" callback('a', MountOperation::Completed, i); "
" } "
" int main(void) "
" { "
" MountOperation aExample(10); "
" } "
2021-08-07 20:51:18 +02:00
) ;
2011-01-19 01:58:44 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void testDoesNotIdentifyMethodAsLastFunctionArgument ( ) {
2012-07-07 20:21:08 +02:00
check ( " void callback(int arg, void (*func)(int)) "
2011-01-19 01:58:44 +01:00
" { "
" (*func)(arg); "
" } "
" class MountOperation "
" { "
" static void Completed(int i); "
" public: "
" MountOperation(int i); "
" }; "
" void MountOperation::Completed(int i) "
" { "
" std::cerr << i << std::endl; "
" } "
" MountOperation::MountOperation(int i) "
" { "
" callback(i, MountOperation::Completed); "
" } "
" int main(void) "
" { "
" MountOperation aExample(10); "
" } "
2021-08-07 20:51:18 +02:00
) ;
2011-01-19 01:58:44 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-01-18 11:50:22 +01:00
}
2011-02-11 14:00:41 +01:00
2014-11-20 14:20:09 +01:00
void multiFile ( ) { // ticket #2567
2011-02-11 14:00:41 +01:00
check ( " #file \" test.h \" \n "
" struct Fred \n "
" { \n "
" Fred() \n "
" { \n "
" Init(); \n "
" } \n "
" private: \n "
" void Init(); \n "
" }; \n "
" #endfile \n "
" void Fred::Init() \n "
" { \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-02-11 14:00:41 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-02-15 01:50:13 +01:00
2014-11-20 14:20:09 +01:00
void unknownBaseTemplate ( ) { // ticket #2580
2011-02-15 01:50:13 +01:00
check ( " class Bla : public Base2<Base> { \n "
" public: \n "
" Bla() {} \n "
" private: \n "
" virtual void F() const; \n "
" }; \n "
" void Bla::F() const { } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2020-12-05 08:00:31 +01:00
void hierarchy_loop ( ) {
2014-03-22 08:49:28 +01:00
check ( " class InfiniteB : InfiniteA { \n "
" class D { \n "
" }; \n "
" }; \n "
" namespace N { \n "
" class InfiniteA : InfiniteB { \n "
" }; \n "
" } \n "
" class InfiniteA : InfiniteB { \n "
" void foo(); \n "
" }; \n "
" void InfiniteA::foo() { \n "
" C a; \n "
" } " ) ;
2015-07-01 00:04:01 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2014-03-22 08:49:28 +01:00
}
2014-11-20 14:20:09 +01:00
void staticVariable ( ) {
2014-08-26 11:29:26 +02:00
check ( " class Foo { \n "
" static int i; \n "
" static int F() const { return 1; } \n "
" }; \n "
" int Foo::i = Foo::F(); " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " class Foo { \n "
" static int i; \n "
" int F() const { return 1; } \n "
" }; \n "
" Foo f; \n "
" int Foo::i = f.F(); " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " class Foo { \n "
" static int i; \n "
" static int F() const { return 1; } \n "
" }; \n "
" int Foo::i = sth(); "
" int i = F(); " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unused private function: 'Foo::F' \n " , errout . str ( ) ) ;
}
2018-12-29 11:19:53 +01:00
void templateSimplification ( ) { //ticket #6183
check ( " class CTest { \n "
" public: \n "
" template <typename T> \n "
" static void Greeting(T val) { \n "
" std::cout << val << std::endl; \n "
" } \n "
" private: \n "
" static void SayHello() { \n "
" std::cout << \" Hello World! \" << std::endl; \n "
" } \n "
" }; \n "
" template<> \n "
" void CTest::Greeting(bool) { \n "
" CTest::SayHello(); \n "
" } \n "
" int main() { \n "
" CTest::Greeting<bool>(true); \n "
" return 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2022-11-10 20:58:39 +01:00
void maybeUnused ( ) {
check ( " class C { \n "
" [[maybe_unused]] int f() { return 42; } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2008-12-18 22:28:57 +01:00
} ;
2009-01-05 16:49:57 +01:00
REGISTER_TEST ( TestUnusedPrivateFunction )