2008-12-19 22:15:18 +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-19 22:15:18 +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-19 22:15:18 +01:00
*/
2009-10-25 12:49:06 +01:00
# include "tokenize.h"
# include "checkother.h"
2008-12-19 22:15:18 +01:00
# include "testsuite.h"
# include <sstream>
extern std : : ostringstream errout ;
class TestOther : public TestFixture
{
public :
TestOther ( ) : TestFixture ( " TestOther " )
{ }
private :
void run ( )
{
2009-03-28 07:49:47 +01:00
TEST_CASE ( zeroDiv1 ) ;
TEST_CASE ( zeroDiv2 ) ;
2009-08-23 05:34:19 +02:00
TEST_CASE ( zeroDiv3 ) ;
2009-08-30 21:02:09 +02:00
TEST_CASE ( zeroDiv4 ) ;
2009-03-28 07:49:47 +01:00
2009-01-15 17:57:51 +01:00
TEST_CASE ( sprintf1 ) ; // Dangerous usage of sprintf
2009-01-10 12:19:17 +01:00
TEST_CASE ( sprintf2 ) ;
2009-01-10 15:29:59 +01:00
TEST_CASE ( sprintf3 ) ;
2009-01-15 17:57:51 +01:00
TEST_CASE ( sprintf4 ) ; // struct member
2010-02-01 19:46:51 +01:00
TEST_CASE ( strPlusChar1 ) ; // "/usr" + '/'
TEST_CASE ( strPlusChar2 ) ; // "/usr" + ch
TEST_CASE ( strPlusChar3 ) ; // ok: path + "/sub" + '/'
2009-02-04 19:49:19 +01:00
2009-03-24 20:24:03 +01:00
TEST_CASE ( varScope1 ) ;
2009-03-24 20:59:56 +01:00
TEST_CASE ( varScope2 ) ;
2009-05-27 19:38:26 +02:00
TEST_CASE ( varScope3 ) ;
2009-06-12 16:17:51 +02:00
TEST_CASE ( varScope4 ) ;
2009-08-16 21:12:57 +02:00
TEST_CASE ( varScope5 ) ;
2009-09-17 21:05:12 +02:00
TEST_CASE ( varScope6 ) ;
2009-10-06 17:45:28 +02:00
TEST_CASE ( varScope7 ) ;
2010-01-21 18:50:56 +01:00
TEST_CASE ( varScope8 ) ;
2010-04-09 16:53:27 +02:00
TEST_CASE ( varScope9 ) ; // classes may have extra side-effects
2010-08-26 21:57:48 +02:00
TEST_CASE ( varScope10 ) ; // Undefined macro FOR
2009-03-27 17:19:34 +01:00
TEST_CASE ( nullpointer1 ) ;
2009-05-10 08:43:16 +02:00
TEST_CASE ( nullpointer2 ) ;
2009-07-21 17:00:11 +02:00
TEST_CASE ( nullpointer3 ) ; // dereferencing struct and then checking if it's null
2009-07-23 14:13:46 +02:00
TEST_CASE ( nullpointer4 ) ;
2009-10-19 17:32:43 +02:00
TEST_CASE ( nullpointer5 ) ; // References should not be checked
TEST_CASE ( nullpointer6 ) ;
2009-11-01 12:08:37 +01:00
TEST_CASE ( nullpointer7 ) ;
2010-03-26 16:44:46 +01:00
TEST_CASE ( nullpointer8 ) ;
2010-06-09 01:21:52 +02:00
TEST_CASE ( nullpointer9 ) ;
2010-10-25 19:43:54 +02:00
TEST_CASE ( nullpointer10 ) ; // check if pointer is null and then dereference it
2009-06-18 22:26:21 +02:00
2009-10-29 21:34:43 +01:00
TEST_CASE ( uninitvar1 ) ;
2010-01-24 15:23:21 +01:00
TEST_CASE ( uninitvar_alloc ) ; // data is allocated but not initialized
TEST_CASE ( uninitvar_arrays ) ; // arrays
TEST_CASE ( uninitvar_class ) ; // class/struct
TEST_CASE ( uninitvar_enum ) ; // enum variables
2010-09-17 20:38:37 +02:00
TEST_CASE ( uninitvar_if ) ; // handling if
TEST_CASE ( uninitvar_loops ) ; // handling for/while
2010-06-03 20:02:58 +02:00
TEST_CASE ( uninitvar_switch ) ; // handling switch
2010-01-24 15:23:21 +01:00
TEST_CASE ( uninitvar_references ) ; // references
2010-02-05 17:35:18 +01:00
TEST_CASE ( uninitvar_strncpy ) ; // strncpy doesn't always 0-terminate
2010-01-24 15:23:21 +01:00
TEST_CASE ( uninitvar_func ) ; // analyse functions
2009-10-29 21:34:43 +01:00
2009-06-18 22:26:21 +02:00
TEST_CASE ( oldStylePointerCast ) ;
2009-07-25 00:36:15 +02:00
2009-10-04 10:05:58 +02:00
TEST_CASE ( dangerousStrolUsage ) ;
TEST_CASE ( passedByValue ) ;
2010-04-02 02:19:38 +02:00
2010-04-02 07:32:03 +02:00
TEST_CASE ( mathfunctionCall1 ) ;
2010-04-13 19:30:25 +02:00
TEST_CASE ( emptyStringTest ) ;
2010-05-04 08:14:45 +02:00
TEST_CASE ( fflushOnInputStreamTest ) ;
2010-05-15 14:06:45 +02:00
TEST_CASE ( sizeofsizeof ) ;
2010-08-06 22:57:10 +02:00
TEST_CASE ( sizeofCalculation ) ;
2010-06-15 08:45:46 +02:00
2010-06-30 09:10:30 +02:00
TEST_CASE ( switchRedundantAssignmentTest ) ;
2010-08-14 15:15:12 +02:00
2010-08-15 06:28:22 +02:00
TEST_CASE ( selfAssignment ) ;
2010-08-14 15:15:12 +02:00
TEST_CASE ( testScanf1 ) ;
TEST_CASE ( testScanf2 ) ;
2010-10-01 17:23:22 +02:00
TEST_CASE ( trac1132 ) ;
TEST_CASE ( testMisusedScopeObjectDoesNotPickFunction ) ;
TEST_CASE ( testMisusedScopeObjectPicksClass ) ;
TEST_CASE ( testMisusedScopeObjectPicksStruct ) ;
TEST_CASE ( testMisusedScopeObjectDoesNotPickIf ) ;
TEST_CASE ( testMisusedScopeObjectDoesNotPickConstructorDeclaration ) ;
2010-10-02 10:43:12 +02:00
TEST_CASE ( testMisusedScopeObjectDoesNotPickFunctor ) ;
2010-10-02 14:59:04 +02:00
TEST_CASE ( testMisusedScopeObjectDoesNotPickLocalClassConstructors ) ;
2010-10-02 12:26:29 +02:00
TEST_CASE ( testMisusedScopeObjectDoesNotPickUsedObject ) ;
2010-10-03 23:16:11 +02:00
TEST_CASE ( trac2071 ) ;
2010-10-13 11:31:41 +02:00
TEST_CASE ( trac2084 ) ;
2010-10-10 22:05:06 +02:00
TEST_CASE ( assignmentInAssert ) ;
2010-10-25 03:14:21 +02:00
TEST_CASE ( incorrectLogicOperator ) ;
2008-12-19 22:15:18 +01:00
}
2009-01-05 16:49:57 +01:00
void check ( const char code [ ] )
2008-12-19 22:15:18 +01:00
{
// Tokenize..
Tokenizer tokenizer ;
std : : istringstream istr ( code ) ;
2009-01-05 16:49:57 +01:00
tokenizer . tokenize ( istr , " test.cpp " ) ;
2008-12-19 22:15:18 +01:00
2010-04-21 08:38:25 +02:00
// Check..
2009-03-20 18:16:21 +01:00
Settings settings ;
2010-04-21 08:38:25 +02:00
settings . _checkCodingStyle = true ;
2009-03-20 18:16:21 +01:00
CheckOther checkOther ( & tokenizer , & settings , this ) ;
2010-05-15 14:06:45 +02:00
// Clear the error buffer..
errout . str ( " " ) ;
checkOther . sizeofsizeof ( ) ;
2010-08-06 22:57:10 +02:00
checkOther . sizeofCalculation ( ) ;
2010-06-30 09:10:30 +02:00
checkOther . checkRedundantAssignmentInSwitch ( ) ;
2010-10-10 22:05:06 +02:00
checkOther . checkAssignmentInAssert ( ) ;
2010-05-15 14:06:45 +02:00
// Simplify token list..
tokenizer . simplifyTokenList ( ) ;
2009-07-05 22:16:43 +02:00
checkOther . checkZeroDivision ( ) ;
2010-04-02 07:32:03 +02:00
checkOther . checkMathFunctions ( ) ;
2010-04-13 19:30:25 +02:00
checkOther . checkEmptyStringTest ( ) ;
2010-05-04 08:14:45 +02:00
checkOther . checkFflushOnInputStream ( ) ;
2010-08-15 06:28:22 +02:00
checkOther . checkSelfAssignment ( ) ;
2010-08-14 15:15:12 +02:00
checkOther . invalidScanf ( ) ;
2010-10-01 17:23:22 +02:00
checkOther . checkMisusedScopedObject ( ) ;
2010-10-25 03:14:21 +02:00
checkOther . checkIncorrectLogicOperator ( ) ;
2008-12-19 22:15:18 +01:00
}
2009-03-27 17:19:34 +01:00
2009-03-28 07:49:47 +01:00
void zeroDiv1 ( )
{
check ( " void foo() \n "
" { \n "
" int a = 0; \n "
" double b = 1.; \n "
" cout<<b/a; \n "
" } " ) ;
2009-05-31 21:48:55 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (error) Division by zero \n " , errout . str ( ) ) ;
2009-03-28 07:49:47 +01:00
}
void zeroDiv2 ( )
{
check ( " void foo() \n "
" { \n "
" int sum = 0; \n "
" int n = 100; \n "
" for(int i = 0; i < n; i ++) \n "
" { \n "
" sum += i; \n "
" } \n "
" cout<<b/sum; \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-03-28 07:49:47 +01:00
2009-06-05 23:33:13 +02:00
check ( " void foo() \n "
" { \n "
" int a = 0 ? (2/0) : 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-03-28 07:49:47 +01:00
2009-08-23 05:34:19 +02:00
void zeroDiv3 ( )
{
check ( " void f() \n "
" { \n "
" div_t divresult = div (1,0); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Division by zero \n " , errout . str ( ) ) ;
}
2009-08-30 21:02:09 +02:00
void zeroDiv4 ( )
{
check ( " void f() \n "
" { \n "
" long a = b / 0x6; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" long a = b / 0x0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Division by zero \n " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" long a = b / 0L; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Division by zero \n " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" long a = b / 0ul; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Division by zero \n " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" div_t divresult = div (1,0L); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Division by zero \n " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" div_t divresult = div (1,0x5); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-01 16:00:26 +02:00
2009-09-01 21:06:46 +02:00
// Don't warn about floating points (gcc doesn't warn either)
// and floating points are handled differently than integers.
2009-09-01 16:00:26 +02:00
check ( " void f() \n "
" { \n "
" long a = b / 0.0; \n "
" } \n " ) ;
2009-09-01 21:06:46 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-01 16:00:26 +02:00
check ( " void f() \n "
" { \n "
" long a = b / 0.5; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-01 21:06:46 +02:00
// Don't warn about 0.0
2009-09-01 16:00:26 +02:00
check ( " void f() \n "
" { \n "
" div_t divresult = div (1,0.0); \n "
" } \n " ) ;
2009-09-01 21:06:46 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-01 16:00:26 +02:00
check ( " void f() \n "
" { \n "
" div_t divresult = div (1,0.5); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-08-30 21:02:09 +02:00
}
2009-01-08 22:08:14 +01:00
2009-01-08 07:24:08 +01:00
void sprintfUsage ( const char code [ ] )
{
// Tokenize..
Tokenizer tokenizer ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
tokenizer . setVarId ( ) ;
2009-01-11 11:03:21 +01:00
//tokenizer.tokens()->printOut( "tokens" );
2009-01-08 07:24:08 +01:00
// Clear the error buffer..
errout . str ( " " ) ;
// Check for redundant code..
2009-03-20 18:16:21 +01:00
Settings settings ;
CheckOther checkOther ( & tokenizer , & settings , this ) ;
2009-07-05 22:16:43 +02:00
checkOther . invalidFunctionUsage ( ) ;
2009-01-08 07:24:08 +01:00
}
2009-01-08 22:08:14 +01:00
2009-01-08 07:24:08 +01:00
void sprintf1 ( )
{
2009-01-08 22:08:14 +01:00
sprintfUsage ( " void foo() \n "
" { \n "
" char buf[100]; \n "
" sprintf(buf, \" %s \" ,buf); \n "
" } \n " ) ;
2009-12-21 21:05:55 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Undefined behaviour: buf is used wrong in call to sprintf or snprintf. Quote: If copying takes place between objects that overlap as a result of a call to sprintf() or snprintf(), the results are undefined. \n " , errout . str ( ) ) ;
2009-01-08 07:24:08 +01:00
}
2009-01-10 12:19:17 +01:00
void sprintf2 ( )
{
sprintfUsage ( " void foo() \n "
" { \n "
" char buf[100]; \n "
" sprintf(buf, \" %i \" ,sizeof(buf)); \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-01-10 12:19:17 +01:00
}
2009-01-10 15:27:31 +01:00
2009-01-10 15:29:59 +01:00
void sprintf3 ( )
{
2009-01-10 15:27:31 +01:00
sprintfUsage ( " void foo() \n "
" { \n "
" char buf[100]; \n "
" sprintf(buf, \" %i \" ,sizeof(buf)); \n "
2009-01-10 15:29:59 +01:00
" if (buf[0]); \n "
2009-01-10 15:27:31 +01:00
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-01-10 15:29:59 +01:00
}
2009-01-10 15:27:31 +01:00
2009-01-11 11:03:21 +01:00
void sprintf4 ( )
{
sprintfUsage ( " struct A \n "
" { \n "
" char filename[128]; \n "
" }; \n "
" \n "
" void foo() \n "
" { \n "
" const char* filename = \" hello \" ; \n "
" struct A a; \n "
" snprintf(a.filename, 128, \" %s \" , filename); \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-01-11 11:03:21 +01:00
}
2009-01-15 17:57:51 +01:00
void strPlusChar ( const char code [ ] )
{
// Tokenize..
Tokenizer tokenizer ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
tokenizer . setVarId ( ) ;
// Clear the error buffer..
errout . str ( " " ) ;
// Check for redundant code..
2009-03-20 18:16:21 +01:00
Settings settings ;
CheckOther checkOther ( & tokenizer , & settings , this ) ;
2009-01-15 17:57:51 +01:00
checkOther . strPlusChar ( ) ;
}
void strPlusChar1 ( )
{
// Strange looking pointer arithmetic..
strPlusChar ( " void foo() \n "
" { \n "
" const char *p = \" /usr \" + '/'; \n "
" } \n " ) ;
2009-05-31 21:48:55 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Unusual pointer arithmetic \n " , errout . str ( ) ) ;
2009-01-15 17:57:51 +01:00
}
2009-01-15 18:12:33 +01:00
void strPlusChar2 ( )
{
// Strange looking pointer arithmetic..
strPlusChar ( " void foo() \n "
" { \n "
2010-02-07 21:44:11 +01:00
" char ch = 1; \n "
" const char *p = ch + \" /usr \" ; \n "
2009-01-15 18:12:33 +01:00
" } \n " ) ;
2010-02-07 21:44:11 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-02-08 08:35:53 +01:00
// Strange looking pointer arithmetic..
2010-02-07 21:44:11 +01:00
strPlusChar ( " void foo() \n "
" { \n "
" int i = 1; \n "
2010-02-22 21:30:21 +01:00
" const char* psz = \" Bla \" ; \n "
2010-02-07 21:44:11 +01:00
" const std::string str = i + psz; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-02-08 08:35:53 +01:00
}
2009-01-15 18:12:33 +01:00
2009-01-18 18:42:41 +01:00
void strPlusChar3 ( )
{
// Strange looking pointer arithmetic..
strPlusChar ( " void foo() \n "
" { \n "
" std::string temp = \" /tmp \" ; \n "
" std::string path = temp + '/' + \" sub \" + '/'; \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-01-18 18:42:41 +01:00
}
2009-02-04 19:49:19 +01:00
2009-03-24 20:24:03 +01:00
void varScope ( const char code [ ] )
{
// Tokenize..
Tokenizer tokenizer ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
// Clear the error buffer..
errout . str ( " " ) ;
// Check for redundant code..
Settings settings ;
settings . _checkCodingStyle = true ;
CheckOther checkOther ( & tokenizer , & settings , this ) ;
2009-07-05 22:16:43 +02:00
checkOther . checkVariableScope ( ) ;
2009-03-24 20:24:03 +01:00
}
void varScope1 ( )
{
varScope ( " unsigned short foo() \n "
" { \n "
" test_client CClient; \n "
" try \n "
" { \n "
" if (CClient.Open()) \n "
" { \n "
" return 0; \n "
" } \n "
" } \n "
" catch (...) \n "
" { \n "
" return 2; \n "
" } \n "
" \n "
" try \n "
" { \n "
" CClient.Close(); \n "
" } \n "
" catch (...) \n "
" { \n "
" return 2; \n "
" } \n "
" \n "
" return 1; \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-03-24 20:24:03 +01:00
}
2009-03-24 20:59:56 +01:00
void varScope2 ( )
{
varScope ( " int foo() \n "
" { \n "
" Error e; \n "
" e.SetValue(12); \n "
" throw e; \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-03-24 20:59:56 +01:00
}
2009-03-27 17:19:34 +01:00
2009-05-27 19:38:26 +02:00
void varScope3 ( )
{
varScope ( " void foo() \n "
" { \n "
" int i; \n "
" int *p = 0; \n "
" if (abc) \n "
" { \n "
" p = &i; \n "
" } \n "
" *p = 1; \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-05-27 19:38:26 +02:00
}
2009-06-12 16:17:51 +02:00
void varScope4 ( )
{
varScope ( " void foo() \n "
" { \n "
" int i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-08-16 21:12:57 +02:00
void varScope5 ( )
{
2009-09-29 23:56:43 +02:00
varScope ( " void f(int x) \n "
" { \n "
" int i = 0; \n "
" if (x) { \n "
" for ( ; i < 10; ++i) ; \n "
" } \n "
" } \n " ) ;
2010-01-12 19:34:33 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) The scope of the variable i can be reduced \n " , errout . str ( ) ) ;
2009-09-29 23:56:43 +02:00
varScope ( " void f(int x) \n "
2009-08-16 21:12:57 +02:00
" { \n "
" int i = 0; \n "
2009-09-29 23:56:43 +02:00
" if (x) {b()} \n "
" else { \n "
2009-08-16 21:12:57 +02:00
" for ( ; i < 10; ++i) ; \n "
" } \n "
" } \n " ) ;
2010-01-12 19:34:33 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) The scope of the variable i can be reduced \n " , errout . str ( ) ) ;
2009-08-16 21:12:57 +02:00
}
2009-03-27 17:19:34 +01:00
2009-09-17 21:05:12 +02:00
void varScope6 ( )
{
varScope ( " void f(int x) \n "
" { \n "
" int i = x; \n "
" if (a) { \n "
" x++; \n "
" } \n "
" if (b) { \n "
" c(i); \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-29 23:56:43 +02:00
varScope ( " void f() \n "
" { \n "
" int foo = 0; \n "
" std::vector<int> vec(10); \n "
" BOOST_FOREACH(int& i, vec) \n "
" { \n "
" foo += 1; \n "
" if(foo == 10) \n "
" { \n "
" return 0; \n "
" } \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-03-27 17:19:34 +01:00
2009-09-29 23:56:43 +02:00
varScope ( " void f(int &x) \n "
" { \n "
" int n = 1; \n "
" do \n "
" { \n "
" ++n; \n "
" ++x; \n "
" } while (x); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-03-27 17:19:34 +01:00
2009-10-06 17:45:28 +02:00
void varScope7 ( )
{
varScope ( " void f(int x) \n "
" { \n "
" int y = 0; \n "
" b(y); \n "
" if (x) { \n "
" y++; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-01-21 18:50:56 +01:00
void varScope8 ( )
{
varScope ( " void test() { \n "
" float edgeResistance=1; \n "
" std::vector<int> edges; \n "
" BOOST_FOREACH(int edge, edges) { \n "
" edgeResistance = (edge+1) / 2.0; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (style) The scope of the variable edgeResistance can be reduced \n " , errout . str ( ) ) ;
}
2010-04-09 16:53:27 +02:00
void varScope9 ( )
{
// classes may have extra side effects
varScope ( " class fred { \n "
" public: \n "
" void x(); \n "
" }; \n "
" void test(int a) { \n "
" fred f; \n "
" if (a == 2) { \n "
" f.x(); \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-26 21:57:48 +02:00
void varScope10 ( )
{
// classes may have extra side effects
varScope ( " int f() \n "
" { \n "
" int x = 0; \n "
" FOR { \n "
" foo(x++); \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-01-21 18:50:56 +01:00
2009-03-27 17:19:34 +01:00
void checkNullPointer ( const char code [ ] )
{
// Tokenize..
Tokenizer tokenizer ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
// Clear the error buffer..
errout . str ( " " ) ;
// Check for redundant code..
Settings settings ;
settings . _checkCodingStyle = true ;
CheckOther checkOther ( & tokenizer , & settings , this ) ;
checkOther . nullPointer ( ) ;
2009-12-21 19:09:13 +01:00
tokenizer . simplifyTokenList ( ) ;
2010-05-26 19:16:42 +02:00
checkOther . nullConstantDereference ( ) ;
2009-12-06 18:41:28 +01:00
checkOther . executionPaths ( ) ;
2010-10-25 21:05:43 +02:00
tokenizer . simplifyTokenList ( ) ;
checkOther . nullPointerByCheckAndDeRef ( ) ;
2009-03-27 17:19:34 +01:00
}
void nullpointer1 ( )
{
checkNullPointer ( " int foo(const Token *tok) \n "
" { \n "
" while (tok); \n "
" tok = tok->next(); \n "
" } \n " ) ;
2009-08-11 17:18:01 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: tok \n " , errout . str ( ) ) ;
2009-07-30 21:57:23 +02:00
checkNullPointer ( " void foo() \n "
" { \n "
" for (const Token *tok = tokens; tok; tok = tok->next()) \n "
" { \n "
" while (tok && tok->str() != \" ; \" ) \n "
" tok = tok->next(); \n "
" } \n "
" } \n " ) ;
2010-02-28 07:26:50 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: tok - otherwise it is redundant to check if tok is null at line 5 \n " , errout . str ( ) ) ;
2009-08-01 11:30:37 +02:00
2009-10-08 10:55:37 +02:00
checkNullPointer ( " void foo(Token &tok) \n "
" { \n "
" for (int i = 0; i < tok.size(); i++ ) \n "
" { \n "
" while (!tok) \n "
" char c = tok.read(); \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-10-07 22:38:21 +02:00
checkNullPointer ( " void foo() \n "
" { \n "
" for (const Token *tok = tokens; tok; tok = tok->next()) \n "
" { \n "
" while (tok && tok->str() != \" ; \" ) \n "
" tok = tok->next(); \n "
" if( !tok ) break; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-08-01 11:30:37 +02:00
checkNullPointer ( " void foo() \n "
" { \n "
" for (const Token *tok = tokens; tok; tok = tok ? tok->next() : NULL) \n "
" { \n "
" while (tok && tok->str() != \" ; \" ) \n "
" tok = tok->next(); \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-10-05 13:46:38 +02:00
checkNullPointer ( " void foo(A*a) \n "
" { \n "
" switch (a->b()) { \n "
" case 1: \n "
" while( a ){ \n "
" a = a->next; \n "
" } \n "
" break; \n "
" case 2: \n "
" a->b(); \n "
" break; \n "
" } \n "
" } \n " ) ;
2010-08-07 19:59:56 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// ticket #1923 - no false positive when using else if
checkNullPointer ( " void f(A *a) \n "
" { \n "
" if (a->x == 1) \n "
" { \n "
" a = a->next; \n "
" } \n "
" else if (a->x == 2) { } \n "
" if (a) { } \n "
" } \n " ) ;
2009-10-05 13:46:38 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-26 18:26:02 +02:00
// ticket #2134 - sizeof doesn't dereference
checkNullPointer ( " void f() { \n "
" int c = 1; \n "
" int *list = NULL; \n "
" sizeof(*list); \n "
" if (!list) \n "
" ; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-03-27 17:19:34 +01:00
}
2009-05-10 08:43:16 +02:00
void nullpointer2 ( )
{
// Null pointer dereference can only happen with pointers
checkNullPointer ( " void foo() \n "
" { \n "
" Fred fred; \n "
" while (fred); \n "
" fred.hello(); \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-05-10 08:43:16 +02:00
}
2009-06-18 22:26:21 +02:00
2009-07-21 17:00:11 +02:00
// Dereferencing a struct and then checking if it is null
2010-08-05 08:06:19 +02:00
// This is checked by this function:
// CheckOther::nullPointerStructByDeRefAndChec
2009-07-21 17:00:11 +02:00
void nullpointer3 ( )
2009-07-20 19:30:33 +02:00
{
2009-07-21 12:09:58 +02:00
// errors..
2009-07-21 17:00:11 +02:00
checkNullPointer ( " void foo(struct ABC *abc) \n "
2009-07-22 18:48:42 +02:00
" { \n "
2009-11-09 20:40:30 +01:00
" int a = abc->a; \n "
2009-07-22 18:48:42 +02:00
" if (!abc) \n "
" ; \n "
" } \n " ) ;
2009-08-21 12:42:40 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 4 \n " , errout . str ( ) ) ;
2009-07-21 12:09:58 +02:00
2009-08-28 08:48:37 +02:00
checkNullPointer ( " void foo(struct ABC *abc) \n "
" { \n "
" bar(abc->a); \n "
" if (!abc) \n "
" ; \n "
" } \n " ) ;
2010-08-05 08:06:19 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 4 \n " , errout . str ( ) ) ;
2009-08-28 08:48:37 +02:00
2009-07-20 19:30:33 +02:00
// ok dereferencing in a condition
2009-07-21 17:00:11 +02:00
checkNullPointer ( " void foo(struct ABC *abc) \n "
2009-07-22 18:48:42 +02:00
" { \n "
" if (abc && abc->a); \n "
" if (!abc) \n "
" ; \n "
" } \n " ) ;
2009-07-20 19:30:33 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// ok to use a linked list..
2009-07-21 17:00:11 +02:00
checkNullPointer ( " void foo(struct ABC *abc) \n "
2009-07-22 18:48:42 +02:00
" { \n "
" abc = abc->next; \n "
" if (!abc) \n "
" ; \n "
" } \n " ) ;
2009-07-20 19:30:33 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-07-20 19:59:55 +02:00
// reassign struct..
2009-07-21 17:00:11 +02:00
checkNullPointer ( " void foo(struct ABC *abc) \n "
2009-07-22 18:48:42 +02:00
" { \n "
2009-11-09 20:40:30 +01:00
" int a = abc->a; \n "
2009-07-22 18:48:42 +02:00
" abc = abc->next; \n "
" if (!abc) \n "
" ; \n "
" } \n " ) ;
2009-07-21 12:09:58 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-07-21 17:00:11 +02:00
checkNullPointer ( " void foo(struct ABC *abc) \n "
2009-07-22 18:48:42 +02:00
" { \n "
2009-11-09 20:40:30 +01:00
" int a = abc->a; \n "
2009-07-22 18:48:42 +02:00
" f(&abc); \n "
" if (!abc) \n "
" ; \n "
" } \n " ) ;
2009-07-21 12:09:58 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// goto..
2009-07-21 17:00:11 +02:00
checkNullPointer ( " void foo(struct ABC *abc) \n "
2009-07-22 18:48:42 +02:00
" { \n "
2009-11-09 20:40:30 +01:00
" int a; \n "
2009-07-22 18:48:42 +02:00
" if (!abc) \n "
" goto out; "
" a = abc->a; \n "
" return; \n "
" out: \n "
" if (!abc) \n "
" ; \n "
" } \n " ) ;
2009-07-20 19:59:55 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-07-23 19:59:29 +02:00
2009-07-29 11:17:22 +02:00
// loops..
2009-07-23 19:59:29 +02:00
checkNullPointer ( " void freeAbc(struct ABC *abc) \n "
" { \n "
" while (abc) \n "
" { \n "
" struct ABC *next = abc->next; \n "
" if (abc) delete abc; \n "
" abc = next; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-07-29 11:17:22 +02:00
checkNullPointer ( " void foo(struct ABC *abc) \n "
" { \n "
" int a = abc->a; "
" do \n "
" { \n "
" if (abc) \n "
" abc = abc->next; \n "
" --a; \n "
" } \n "
2009-08-11 21:06:41 +02:00
" while (a > 0); \n "
2009-07-29 11:17:22 +02:00
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-19 10:54:10 +02:00
2010-09-02 21:08:58 +02:00
checkNullPointer ( " void f() \n "
" { \n "
" for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) \n "
" { \n "
" while (tok && tok->str() != \" { \" ) \n "
" tok = tok->next(); \n "
" if (!tok) \n "
" return; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-19 10:54:10 +02:00
// dynamic_cast..
checkNullPointer ( " void foo(ABC *abc) \n "
" { \n "
" int a = abc->a; \n "
" if (!dynamic_cast<DEF *>(abc)) \n "
" ; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-07-20 19:30:33 +02:00
}
2009-07-23 14:13:46 +02:00
// Dereferencing a pointer and then checking if it is null
void nullpointer4 ( )
{
// errors..
checkNullPointer ( " void foo(int *p) \n "
" { \n "
" *p = 0; \n "
" if (!p) \n "
" ; \n "
" } \n " ) ;
2010-08-05 08:19:36 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 4 \n " , errout . str ( ) ) ;
2009-07-23 14:13:46 +02:00
2009-08-28 08:48:37 +02:00
checkNullPointer ( " void foo(int *p) \n "
" { \n "
" bar(*p); \n "
" if (!p) \n "
" ; \n "
" } \n " ) ;
2010-08-05 08:19:36 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 4 \n " , errout . str ( ) ) ;
2009-08-28 08:48:37 +02:00
2009-07-23 14:13:46 +02:00
// no error
2009-07-23 19:02:14 +02:00
checkNullPointer ( " void foo() \n "
" { \n "
" int *p; \n "
" f(&p); \n "
" if (!p) \n "
" ; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkNullPointer ( " void foo() \n "
" { \n "
" int **p = f(); \n "
" if (!p) \n "
" ; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-07-23 14:13:46 +02:00
checkNullPointer ( " void foo(int *p) \n "
" { \n "
" if (x) \n "
" p = 0; \n "
" else \n "
" *p = 0; \n "
" if (!p) \n "
" ; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-07-25 20:36:02 +02:00
checkNullPointer ( " void foo(int x) \n "
" { \n "
" int a = 2 * x; "
" if (x == 0) \n "
" ; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-08-28 08:48:37 +02:00
checkNullPointer ( " void foo(int *p) \n "
" { \n "
" int var1 = p ? *p : 0; \n "
" if (!p) \n "
" ; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-29 15:38:05 +02:00
checkNullPointer ( " void foo(P *p) \n "
" { \n "
" while (p) \n "
" if (p->check()) \n "
" break; \n "
" else \n "
" p = p->next(); \n "
" } \n " ) ;
2009-09-30 20:42:14 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-07-23 14:13:46 +02:00
}
2009-10-08 10:55:37 +02:00
void nullpointer5 ( )
{
// errors..
checkNullPointer ( " void foo(A &a) \n "
" { \n "
" char c = a.c(); \n "
" if (!a) \n "
" return; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-07-23 14:13:46 +02:00
2010-05-26 19:16:42 +02:00
// Execution paths..
2009-10-19 17:32:43 +02:00
void nullpointer6 ( )
{
// errors..
checkNullPointer ( " static void foo() \n "
" { \n "
" Foo *p = 0; \n "
" if (a == 1) \n "
" p = new FooBar; \n "
" else if (a == 2) \n "
" p = new FooCar; \n "
" p->abcd(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:8]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
2009-10-20 20:57:38 +02:00
2009-12-21 19:09:13 +01:00
checkNullPointer ( " static void foo() \n "
" { \n "
" int *p = 0; \n "
" int *q = p; \n "
" q[0] = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (error) Possible null pointer dereference: q \n " , errout . str ( ) ) ;
2009-12-30 17:42:41 +01:00
checkNullPointer ( " static void foo() \n "
" { \n "
" int *p = 0; \n "
" int &r = *p; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2009-12-21 19:09:13 +01:00
2009-12-31 20:00:20 +01:00
checkNullPointer ( " static void foo(int x) \n "
" { \n "
" int *p = 0; \n "
" int y = 5 + *p; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2010-01-03 13:30:20 +01:00
checkNullPointer ( " static void foo(int x) \n "
" { \n "
" Foo<int> *abc = 0; \n "
" abc->a(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: abc \n " , errout . str ( ) ) ;
2010-01-30 14:40:33 +01:00
checkNullPointer ( " static void foo() \n "
" { \n "
" int *p(0); \n "
" std::cout << *p; "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2010-04-28 22:07:39 +02:00
checkNullPointer ( " void f() \n "
" { \n "
" char *c = 0; \n "
" { \n "
" delete c; \n "
" } \n "
" c[0] = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:7]: (error) Possible null pointer dereference: c \n " , errout . str ( ) ) ;
2010-06-06 12:15:31 +02:00
checkNullPointer ( " static void foo() \n "
" { \n "
" int *p = 0; \n "
" if (3 > *p); \n "
" } \n " ) ;
2010-06-19 14:00:45 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2010-06-06 12:15:31 +02:00
2010-05-26 19:16:42 +02:00
checkNullPointer ( " void f() \n "
" { \n "
" if (x) { \n "
" char *c = 0; \n "
" *c = 0; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2009-10-20 20:57:38 +02:00
// no false positive..
checkNullPointer ( " static void foo() \n "
" { \n "
" Foo *p = 0; \n "
" p = new Foo; \n "
" p->abcd(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-10-30 15:14:24 +01:00
checkNullPointer ( " static void foo() \n "
" { \n "
" Foo *p = 0; \n "
" if (!p) \n "
" return; \n "
" p->abcd(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-29 09:17:07 +01:00
2010-01-03 15:35:32 +01:00
checkNullPointer ( " static void foo() \n "
" { \n "
" int *p = 0; \n "
" exit(); \n "
" *p = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-29 09:17:07 +01:00
checkNullPointer ( " static void foo(int a) \n "
" { \n "
" Foo *p = 0; \n "
" if (a && p) \n "
" p->do_something(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-14 20:02:38 +01:00
checkNullPointer ( " void foo() \n "
" { \n "
" int sz = sizeof((*(struct dummy *)0).x); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-23 09:15:30 +01:00
2010-02-22 21:30:21 +01:00
checkNullPointer ( " void get_offset(long &offset) \n "
" { \n "
" mystruct * temp; temp = 0; \n "
" offset = (long)(&(temp->z)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-07-24 14:27:18 +02:00
// Ticket #1893 - try/catch inside else
checkNullPointer ( " int *test(int *Z) \n "
" { \n "
" int *Q=NULL; \n "
" if (Z) { \n "
" Q = Z; \n "
" } \n "
" else { \n "
" Z = new int; \n "
" try { \n "
" } catch(...) { \n "
" } \n "
" Q = Z; \n "
" } \n "
" *Q=1; \n "
" return Q; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkNullPointer ( " int *test(int *Z) \n "
" { \n "
" int *Q=NULL; \n "
" if (Z) { \n "
" Q = Z; \n "
" } \n "
" else { \n "
" try { \n "
" } catch(...) { \n "
" } \n "
" } \n "
" *Q=1; \n "
" return Q; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:12]: (error) Possible null pointer dereference: Q \n " , errout . str ( ) ) ;
2010-09-18 14:56:07 +02:00
// Ticket #2052 (false positive for 'else continue;')
checkNullPointer ( " void f() { \n "
" for (int x = 0; x < 5; ++x) { "
" int *p = 0; \n "
" if (a(x)) p=b(x); \n "
" else continue; \n "
" *p = 0; \n "
" } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-23 09:15:30 +01:00
// function pointer..
checkNullPointer ( " void foo() \n "
" { \n "
" void (*f)(); \n "
" f = 0; \n "
" f(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (error) Possible null pointer dereference: f \n " , errout . str ( ) ) ;
2010-02-25 21:55:09 +01:00
checkNullPointer ( " static void foo() \n "
" { \n "
" int *p = 0; \n "
" int *p2 = 0; \n "
" int r = *p; \n "
" int r2 = *p2; \n "
" } \n " ) ;
2010-04-04 11:24:52 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (error) Null pointer dereference \n "
" [test.cpp:6]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2010-02-25 21:55:09 +01:00
2010-10-24 18:51:14 +02:00
// loops..
checkNullPointer ( " void f() { \n "
" int *p = 0; \n "
" for (int i = 0; i < 10; ++i) { \n "
" int x = *p + 1; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
2009-10-19 17:32:43 +02:00
}
2009-11-01 12:08:37 +01:00
void nullpointer7 ( )
{
checkNullPointer ( " void foo() \n "
" { \n "
" wxLongLong x = 0; \n "
" int y = x.GetValue(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-10-29 21:34:43 +01:00
2010-03-26 16:44:46 +01:00
void nullpointer8 ( )
{
checkNullPointer ( " void foo() \n "
" { \n "
" const char * x = 0; \n "
" strdup(x); \n "
" } \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: x \n " , errout . str ( ) ) ;
2010-03-26 16:44:46 +01:00
checkNullPointer ( " void foo() \n "
" { \n "
" char const * x = 0; \n "
" strdup(x); \n "
" } \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: x \n " , errout . str ( ) ) ;
2010-03-26 16:44:46 +01:00
}
2010-06-09 01:21:52 +02:00
void nullpointer9 ( ) //#ticket 1778
{
checkNullPointer ( " void foo() \n "
" { \n "
" std::string * x = 0; \n "
" *x = \" test \" ; \n "
" } \n " ) ;
2010-10-09 07:57:34 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: x \n " , errout . str ( ) ) ;
2010-06-09 01:21:52 +02:00
}
2010-10-25 19:43:54 +02:00
// Check if pointer is null and the dereference it
void nullpointer10 ( )
{
checkNullPointer ( " void foo(char *p) { \n "
" if (!p) { \n "
" } \n "
" *p = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
checkNullPointer ( " void foo(abc *p) { \n "
" if (!p) { \n "
" } \n "
" else if (!p->x) { \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-26 17:40:30 +02:00
checkNullPointer ( " void foo(char *p) { \n "
" if (!p) { \n "
" abort(); \n "
" } \n "
" *p = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-25 19:43:54 +02:00
}
2009-10-29 21:34:43 +01:00
void checkUninitVar ( const char code [ ] )
{
// Tokenize..
Tokenizer tokenizer ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
2010-07-06 13:18:28 +02:00
tokenizer . simplifyTokenList ( ) ;
2009-10-29 21:34:43 +01:00
// Clear the error buffer..
errout . str ( " " ) ;
// Check for redundant code..
Settings settings ;
CheckOther checkOther ( & tokenizer , & settings , this ) ;
2009-12-06 18:41:28 +01:00
checkOther . executionPaths ( ) ;
2009-10-29 21:34:43 +01:00
}
void uninitvar1 ( )
{
2009-10-30 14:31:37 +01:00
// dereferencing uninitialized pointer..
checkUninitVar ( " static void foo() \n "
" { \n "
" Foo *p; \n "
" p->abcd(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: p \n " , errout . str ( ) ) ;
2010-01-03 13:30:20 +01:00
checkUninitVar ( " static void foo() \n "
" { \n "
" Foo<int> *p; \n "
" p->abcd(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: p \n " , errout . str ( ) ) ;
2010-05-30 10:30:51 +02:00
checkUninitVar ( " void f(Foo *p) \n "
" { \n "
" int a; \n "
" p->a = malloc(4 * a); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: a \n " , errout . str ( ) ) ;
2009-11-15 20:01:57 +01:00
checkUninitVar ( " static void foo() \n "
" { \n "
" int *p; \n "
" delete p; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: p \n " , errout . str ( ) ) ;
checkUninitVar ( " static void foo() \n "
" { \n "
" int *p; \n "
" delete [] p; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: p \n " , errout . str ( ) ) ;
2009-11-15 20:26:07 +01:00
checkUninitVar ( " static void foo() \n "
" { \n "
" int *p; \n "
" *p = 135; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: p \n " , errout . str ( ) ) ;
2009-12-27 17:20:34 +01:00
checkUninitVar ( " static void foo() \n "
" { \n "
" int *x; \n "
" int y = *x; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: x \n " , errout . str ( ) ) ;
2009-12-29 20:36:20 +01:00
checkUninitVar ( " static void foo() \n "
" { \n "
" int *x; \n "
" int &y(*x); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: x \n " , errout . str ( ) ) ;
2009-12-30 21:42:15 +01:00
checkUninitVar ( " void foo() \n "
" { \n "
" int x; \n "
" int *y = &x; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-03 08:03:28 +01:00
checkUninitVar ( " void foo() \n "
" { \n "
" int x = xyz::x; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-23 17:55:03 +01:00
checkUninitVar ( " static int foo() \n "
" { \n "
" int ret; \n "
" return ret; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: ret \n " , errout . str ( ) ) ;
2009-12-30 20:15:44 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" int a; \n "
" a = 5 + a; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: a \n " , errout . str ( ) ) ;
2010-01-10 09:09:37 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" int a; \n "
" a++; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: a \n " , errout . str ( ) ) ;
2010-05-30 09:31:10 +02:00
checkUninitVar ( " void f() \n "
" { \n "
" int a; \n "
" bar(4 * a); \n "
" } \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: a \n " , errout . str ( ) ) ;
2010-05-30 09:31:10 +02:00
2009-12-25 19:45:21 +01:00
checkUninitVar ( " static void foo() \n "
" { \n "
" int i; \n "
" if (i); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: i \n " , errout . str ( ) ) ;
2010-03-28 21:27:06 +02:00
checkUninitVar ( " static void foo() \n "
" { \n "
" int i; \n "
" for (int x = 0; i < 10; x++); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: i \n " , errout . str ( ) ) ;
checkUninitVar ( " static void foo() \n "
" { \n "
" int i; \n "
" for (int x = 0; x < 10; i++); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: i \n " , errout . str ( ) ) ;
2009-12-25 19:45:21 +01:00
2009-12-25 20:50:23 +01:00
checkUninitVar ( " static int foo(int x) \n "
" { \n "
" int i; \n "
" if (x) \n "
" i = 0; \n "
" return i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:6]: (error) Uninitialized variable: i \n " , errout . str ( ) ) ;
2010-01-09 22:26:05 +01:00
checkUninitVar ( " static void foo() \n "
" { \n "
" int ar[10]; \n "
" int i; \n "
" ar[i] = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (error) Uninitialized variable: i \n " , errout . str ( ) ) ;
2009-12-20 13:55:17 +01:00
checkUninitVar ( " static void foo() \n "
" { \n "
" int x, y; \n "
" x = (y = 10); \n "
" int z = y * 2; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-10-30 14:31:37 +01:00
checkUninitVar ( " static void foo() \n "
" { \n "
" Foo p; \n "
" p.abcd(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-23 13:57:01 +01:00
checkUninitVar ( " static void foo() \n "
" { \n "
" Foo p; \n "
" int x = p.abcd(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-10-31 10:30:32 +01:00
checkUninitVar ( " A a() \n "
" { \n "
" A ret; \n "
" return ret; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-07-06 13:18:28 +02:00
checkUninitVar ( " int a() \n "
2009-11-02 19:58:49 +01:00
" { \n "
" int x; \n "
2010-07-06 13:18:28 +02:00
" return x; \n "
2009-11-02 19:58:49 +01:00
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: x \n " , errout . str ( ) ) ;
2009-11-03 17:03:53 +01:00
checkUninitVar ( " void a() \n "
" { \n "
" int x[10]; \n "
" int *y = x; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-11 19:25:01 +01:00
checkUninitVar ( " void a() \n "
" { \n "
" int x; \n "
" int *y = &x; \n "
" *y = 0; \n "
" x++; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-17 19:08:45 +01:00
checkUninitVar ( " void a() \n "
" { \n "
" char x[10], y[10]; \n "
" char *z = x; \n "
" memset(z, 0, sizeof(x)); \n "
" memcpy(y, x, sizeof(x)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-11-02 16:28:15 +01:00
checkUninitVar ( " int a() \n "
" { \n "
" int ret; \n "
" std::cin >> ret; \n "
" return ret; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-11-02 18:31:22 +01:00
checkUninitVar ( " int a() \n "
" { \n "
" int ret; \n "
" asm(); \n "
" return ret; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-11-05 21:07:04 +01:00
checkUninitVar ( " void a() \n "
" { \n "
" int x[10]; \n "
" struct xyz xyz1 = { .x = x }; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-05-30 07:55:11 +02:00
checkUninitVar ( " void a() \n "
" { \n "
" struct S *s; \n "
" s->x = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: s \n " , errout . str ( ) ) ;
2010-05-30 08:26:44 +02:00
checkUninitVar ( " void a() \n "
" { \n "
" struct S *s; \n "
" FOREACH() { } \n "
" s->x = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (error) Uninitialized variable: s \n " , errout . str ( ) ) ;
2010-05-30 09:00:18 +02:00
checkUninitVar ( " void a() \n "
" { \n "
" struct S *s1; \n "
" struct S *s2; \n "
" FOREACH(s1) { } \n "
" s2->x = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:6]: (error) Uninitialized variable: s2 \n " , errout . str ( ) ) ;
2010-03-28 10:42:37 +02:00
// #1533
checkUninitVar ( " char a() \n "
" { \n "
" char key; \n "
" struct A msg = { .buf = {&key} }; \n "
" init(&msg); \n "
" return key; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-27 09:27:05 +01:00
checkUninitVar ( " void foo() \n "
" { \n "
" char *buf = malloc(100); \n "
" struct ABC *abc = buf; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-28 12:51:28 +01:00
checkUninitVar ( " class Fred { \n "
" public: \n "
" FILE *f; \n "
" ~Fred(); \n "
" } \n "
" Fred::~Fred() \n "
" { \n "
" fclose(f); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-02 18:16:44 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" int c; \n "
" ab(sizeof(xyz), &c); \n "
" if (c); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-13 19:37:55 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" int c; \n "
" a = (f2(&c)); \n "
" c++; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-05-27 19:00:52 +02:00
checkNullPointer ( " void f(int a) \n "
" { \n "
" if (a) { \n "
" char *p; \n "
" *p = 0; \n "
" } \n "
" } \n " ) ;
2010-10-24 18:26:59 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (error) Uninitialized variable: p \n " , errout . str ( ) ) ;
2010-05-27 19:00:52 +02:00
2010-01-03 18:49:13 +01:00
// +=
checkUninitVar ( " void f() \n "
" { \n "
" int c; \n "
" c += 2; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: c \n " , errout . str ( ) ) ;
checkUninitVar ( " void f() \n "
" { \n "
" char *s = malloc(100); \n "
" *s += 10; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Data is allocated but not initialized: s \n " , errout . str ( ) ) ;
checkUninitVar ( " void f() \n "
" { \n "
" int a[10]; \n "
" a[0] += 10; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: a \n " , errout . str ( ) ) ;
2010-09-03 07:18:01 +02:00
// goto/setjmp/longjmp..
2009-11-06 16:02:13 +01:00
checkUninitVar ( " void foo(int x) \n "
" { \n "
" long b; \n "
" if (g()) { \n "
" b =2; \n "
" goto found; \n "
" } \n "
" \n "
" return; \n "
" \n "
" found: \n "
" int a = b; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-09-03 07:18:01 +02:00
checkUninitVar ( " int foo() \n "
" { \n "
" jmp_buf env; \n "
" int a; \n "
" int val = setjmp(env); \n "
" if(val) \n "
" return a; \n "
" a = 1; \n "
" longjmp(env, 1); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
// macro_for..
checkUninitVar ( " int foo() \n "
" { \n "
" int retval; \n "
" if (condition) { \n "
" for12(1,2) { } \n "
" retval = 1; \n "
" } \n "
" else \n "
" retval = 2; \n "
" return retval; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-02 08:35:05 +02:00
checkUninitVar ( " int foo() \n "
" { \n "
" int i; \n "
" goto exit; \n "
" i++; \n "
" exit: \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
}
2009-11-06 16:02:13 +01:00
2010-01-24 15:23:21 +01:00
// if..
void uninitvar_if ( )
{
2009-10-29 21:34:43 +01:00
checkUninitVar ( " static void foo() \n "
" { \n "
" Foo *p; \n "
" if (x) \n "
" p = new Foo; \n "
" p->abcd(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:6]: (error) Uninitialized variable: p \n " , errout . str ( ) ) ;
2010-04-25 11:55:57 +02:00
checkUninitVar ( " static void foo(int x) \n "
" { \n "
" int a; \n "
" if (x==1); \n "
" if (x==2); \n "
" x = a; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:6]: (error) Uninitialized variable: a \n " , errout . str ( ) ) ;
2009-10-29 21:34:43 +01:00
checkUninitVar ( " int foo() \n "
" { \n "
" int i; \n "
" if (x) \n "
" i = 22; \n "
" else \n "
" i = 33; \n "
" return i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-11-10 18:05:55 +01:00
checkUninitVar ( " int foo() \n "
" { \n "
" int i; \n "
" if (x) \n "
" i = 22; \n "
" else \n "
" { \n "
" char *y = {0}; \n "
" i = 33; \n "
" } \n "
" return i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-11-14 08:00:17 +01:00
checkUninitVar ( " int foo() \n "
" { \n "
" int i; \n "
" if (x) \n "
" { \n "
" struct abc abc1 = (struct abc) { .a=0, .b=0, .c=0 }; \n "
" i = 22; \n "
" } \n "
" else \n "
" { \n "
" i = 33; \n "
" } \n "
" return i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-25 20:50:23 +01:00
checkUninitVar ( " static void foo(int x) \n "
2009-10-29 21:34:43 +01:00
" { \n "
" Foo *p; \n "
" if (x) \n "
" p = new Foo; \n "
" if (x) \n "
" p->abcd(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-10-29 22:51:08 +01:00
2010-07-06 13:18:28 +02:00
checkUninitVar ( " void foo(int a) \n "
" { \n "
" int n; \n "
" int condition; \n "
" if(a == 1) { \n "
" n=0; \n "
" condition=0; \n "
" } \n "
" else { \n "
" n=1; \n "
" } \n "
" \n "
" if( n == 0) { \n "
" a=condition; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-10-30 18:28:01 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" C *c; \n "
" if (fun(&c)); \n "
" c->Release(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-11-14 20:37:54 +01:00
checkUninitVar ( " int foo(int x) \n "
" { \n "
" int i; \n "
" if (one()) \n "
" i = 1; \n "
" else \n "
" return 3; \n "
" return i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-01 20:12:39 +01:00
checkUninitVar ( " int foo() \n "
" { \n "
" int ret; \n "
" if (one()) \n "
" ret = 1; \n "
" else \n "
" throw 3; \n "
" return ret; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-01 19:43:02 +01:00
checkUninitVar ( " int f(int a) \n "
" { \n "
" int ret; \n "
" if (a == 1) \n "
" ret = 1; \n "
" else \n "
" XYZ ret = 2; \n " // XYZ may be an unexpanded macro so bailout the checking of "ret".
" return ret; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-02 09:08:36 +01:00
checkUninitVar ( " int f(int a, int b) \n "
" { \n "
" int x; \n "
" if (a) \n "
" x = a; \n "
" else { \n "
" do { } while (f2()); \n "
" x = b; \n "
" } \n "
" return x; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-28 21:33:11 +02:00
checkUninitVar ( " void foo(long verbose,bool bFlag) \n "
" { \n "
" double t; \n "
" if (bFlag) \n "
" { \n "
" if (verbose) \n "
" t = 1; \n "
" if (verbose) \n "
" std::cout << (12-t); \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-06-30 08:28:34 +02:00
// ? :
checkUninitVar ( " static void foo(int v) \n "
" { \n "
" int x; \n "
" if (v > 0) \n "
" v = func(&x); \n "
" x = v <= 0 ? -1 : x; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-07-08 11:16:49 +02:00
checkUninitVar ( " void foo() \n "
" { \n "
" const char *msgid1, *msgid2; \n "
" int ret = bar(&msgid1); \n "
" if (ret > 0) { \n "
" ret = bar(&msgid2); \n "
" } \n "
" ret = ret <= 0 ? -1 : \n "
" strcmp(msgid1, msgid2) == 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-09-15 20:04:50 +02:00
checkUninitVar ( " void foo(int a, int b) \n "
" { \n "
" int x; x = (a<b) ? 1 : 0; \n "
" int y = y; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: y \n " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
// ; { .. }
checkUninitVar ( " int foo() \n "
2009-12-23 19:51:32 +01:00
" { \n "
2010-01-24 15:23:21 +01:00
" int retval; \n "
" if (condition) { \n "
" { } \n "
" retval = 1; } \n "
" else \n "
" retval = 2; \n "
" return retval; \n "
2009-12-23 19:51:32 +01:00
" } \n " ) ;
2009-12-30 11:32:46 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-31 09:10:20 +01:00
checkUninitVar ( " void foo() \n "
" { \n "
2010-01-24 15:23:21 +01:00
" { \n "
" for (int i = 0; i < 10; ++i) \n "
" { } \n "
" } \n "
" \n "
" { } \n "
2009-12-31 09:10:20 +01:00
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
}
2009-12-31 09:10:20 +01:00
2010-09-17 20:38:37 +02:00
// handling for/while loops..
void uninitvar_loops ( )
{
// for..
checkUninitVar ( " void f() \n "
" { \n "
" for (int i = 0; i < 4; ++i) { \n "
" int a; \n "
" b(4*a); \n "
" } "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (error) Uninitialized variable: a \n " , errout . str ( ) ) ;
2010-10-24 18:12:48 +02:00
checkUninitVar ( " void f() { \n "
" int k; \n "
" for (int i = 0; i < 4; ++i) { \n "
" k = k + 2; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: k \n " , errout . str ( ) ) ;
2010-10-24 19:14:40 +02:00
checkUninitVar ( " enum ABCD { A, B, C, D }; \n "
" \n "
" static void f(char *str ) { \n "
" enum ABCD i; \n "
" for (i = 0; i < D; i++) { \n "
" str[i] = 0; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-25 20:56:15 +02:00
checkUninitVar ( " void x() { \n "
" do { \n "
" Token * tok; \n "
" for (tok = a; tok; tok = tok->next()) \n "
" { \n "
" } \n "
" } while (tok2); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-09-17 20:38:37 +02:00
// while..
checkUninitVar ( " int f() \n "
" { \n "
" int i; \n "
" while (fgets()) \n "
" i = 1; \n "
" return i; "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:6]: (error) Uninitialized variable: i \n " , errout . str ( ) ) ;
checkUninitVar ( " void f(int i) \n "
" { \n "
" int a; \n "
" while (i < 10) \n "
" i++; \n "
" a++; "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:6]: (error) Uninitialized variable: a \n " , errout . str ( ) ) ;
}
2010-06-03 20:02:58 +02:00
// switch..
void uninitvar_switch ( )
{
checkUninitVar ( " void f(int x) \n "
" { \n "
" short c; \n "
" switch(x) { \n "
" case 1: \n "
" c++; \n "
" break; \n "
" }; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:6]: (error) Uninitialized variable: c \n " , errout . str ( ) ) ;
checkUninitVar ( " char * f() \n "
" { \n "
" static char ret[200]; \n "
" memset(ret, 0, sizeof(ret)); \n "
" switch (x) \n "
" { \n "
" case 1: return ret; \n "
" case 2: return ret; \n "
" } \n "
" return 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkUninitVar ( " int foo(const int iVar, unsigned int slot, unsigned int pin) \n "
" { \n "
" int i; \n "
" \n "
" if (iVar == 0) \n "
" { \n "
" switch (slot) \n "
" { \n "
" case 4: return 5; \n "
" default: return -1; \n "
" } \n "
" } \n "
" else \n "
" { \n "
" switch (pin) \n "
" { \n "
" case 0: i = 2; break; \n "
" default: i = -1; break; \n "
" } \n "
" } \n "
" return i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-06-05 09:45:35 +02:00
// No segmentation fault
checkUninitVar ( " void a() try \n "
" { \n "
" { \n "
" while (1) { \n "
" switch (1) { \n "
" case 1: { \n "
" int i; \n "
" } \n "
" } \n "
" } \n "
" } catch (...) { \n "
" } \n "
" } \n " ) ;
2010-07-18 13:19:37 +02:00
// #1855 - switch(foo(&x))
checkUninitVar ( " int a() \n "
" { \n "
" int x; \n "
" switch (foo(&x)) \n "
" { \n "
" case 1: \n "
" return x; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-06-03 20:02:58 +02:00
}
2010-01-24 15:23:21 +01:00
// arrays..
void uninitvar_arrays ( )
{
2010-04-05 09:04:30 +02:00
checkUninitVar ( " int f() \n "
" { \n "
" char a[10]; \n "
" a[a[0]] = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: a \n " , errout . str ( ) ) ;
2010-06-14 08:36:34 +02:00
checkUninitVar ( " int f() \n "
" { \n "
" char a[10]; \n "
" char c = *a; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: a \n " , errout . str ( ) ) ;
2010-03-16 19:09:37 +01:00
checkUninitVar ( " int f() \n "
" { \n "
" char a[10]; \n "
" *a = ' \\ 0'; \n "
" int i = strlen(a); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-06-25 19:39:30 +02:00
checkUninitVar ( " void f() \n "
" { \n "
" char a, b[10]; \n "
" a = b[0] = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-11-03 21:02:16 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" char a[10], b[10]; \n "
" a[0] = b[0] = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-11-08 07:31:01 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" char a[10], *p; \n "
" *(p = a) = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-11-06 16:50:02 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" char c[50] = \" \" ; \n "
" strcat(c, \" test \" ); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-10-31 16:36:56 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" char s[20]; \n "
" strcpy(s2, s); \n "
" }; \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: s \n " , errout . str ( ) ) ;
2009-11-03 17:03:53 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" char s[20]; \n "
" strcat(s, \" abc \" ); \n "
" }; \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: s \n " , errout . str ( ) ) ;
2009-11-06 19:06:45 +01:00
2009-12-22 21:07:56 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" char s[20]; \n "
" strchr(s, ' '); \n "
" }; \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: s \n " , errout . str ( ) ) ;
2010-07-18 18:55:53 +02:00
checkUninitVar ( " void foo() \n "
" { \n "
" int y[2]; \n "
" int s; \n "
" GetField( y + 0, \n "
" y + 1 ); \n "
" s = y[0]*y[1]; \n "
" } \n " ) ;
2010-07-19 10:03:54 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
}
2009-11-07 09:10:15 +01:00
2010-01-24 15:23:21 +01:00
// alloc..
void uninitvar_alloc ( )
{
2009-11-07 09:10:15 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" char *s = malloc(100); \n "
" strcat(s, \" abc \" ); \n "
" }; \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Data is allocated but not initialized: s \n " , errout . str ( ) ) ;
2009-11-07 09:10:15 +01:00
2009-11-07 14:54:12 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" char *s1 = new char[10]; \n "
" char *s2 = new char[strlen(s1)]; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Data is allocated but not initialized: s1 \n " , errout . str ( ) ) ;
2009-11-29 19:23:31 +01:00
2010-04-05 08:38:26 +02:00
checkUninitVar ( " void f() \n "
" { \n "
" char *p = malloc(64); \n "
" int x = p[0]; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Data is allocated but not initialized: p \n " , errout . str ( ) ) ;
2010-08-04 21:13:40 +02:00
checkUninitVar ( " void f() \n "
" { \n "
" char *p = malloc(64); \n "
" if (p[0]) { } \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Data is allocated but not initialized: p \n " , errout . str ( ) ) ;
checkUninitVar ( " void f() \n "
" { \n "
" char *p = malloc(64); \n "
" return p[0]; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Data is allocated but not initialized: p \n " , errout . str ( ) ) ;
2009-12-22 21:00:52 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" Fred *fred = new Fred; \n "
" fred->foo(); \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-26 09:30:02 +01:00
checkUninitVar ( " void foo(char *s) \n "
" { \n "
" char *a = malloc(100); \n "
" *a = *s; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-26 16:21:53 +01:00
checkUninitVar ( " void foo() \n "
" { \n "
" char *a; \n "
" if (a); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: a \n " , errout . str ( ) ) ;
checkUninitVar ( " void foo() \n "
" { \n "
" char *a = malloc(100); \n "
" if (a); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-27 17:35:18 +01:00
checkUninitVar ( " void foo() \n "
" { \n "
" ABC *abc = malloc(100); \n "
" abc->a = 123; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-03-07 09:08:52 +01:00
checkUninitVar ( " void foo() \n "
" { \n "
" ABC *abc = malloc(100); \n "
" abc->a.word = 123; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-23 21:25:17 +01:00
checkUninitVar ( " void foo() \n "
" { \n "
" ABC *abc = malloc(100); \n "
" abc->a = 123; \n "
" abc->a += 123; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-27 18:00:43 +01:00
checkUninitVar ( " void foo() \n "
" { \n "
" ABC *abc = malloc(100); \n "
" free(abc); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-30 20:37:11 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" char *s = malloc(100); \n "
" if (!s) \n "
" return; \n "
" char c = *s; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " [test.cpp:6]: (error) Data is allocated but not initialized: s \n " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
}
// class / struct..
void uninitvar_class ( )
{
checkUninitVar ( " class Fred \n "
" { \n "
" int i; \n "
" int a() { return i; } \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-30 20:37:11 +01:00
2009-11-29 19:23:31 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" struct Relative { \n "
" Surface *surface; \n "
" void MoveTo(int x, int y) { \n "
" surface->MoveTo(); \n "
" } \n "
" }; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-09 20:05:06 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" static const struct ab { \n "
" int a,b; \n "
" int get_a() { return a; } "
" } = { 0, 0 }; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-02-20 09:35:57 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" int i; \n "
" { \n "
" union ab { \n "
" int a,b; \n "
" } \n "
" i = 0; \n "
" } \n "
" return i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
}
2009-12-15 19:50:48 +01:00
2010-01-24 15:23:21 +01:00
// enum..
void uninitvar_enum ( )
{
2010-01-10 20:36:15 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" enum AB { a, b }; \n "
" AB ab; \n "
" if (ab); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (error) Uninitialized variable: ab \n " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
}
2010-01-10 20:36:15 +01:00
2010-01-24 15:23:21 +01:00
// references..
void uninitvar_references ( )
{
2009-12-15 19:50:48 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" int a; \n "
" int &b = a; \n "
" b = 0; \n "
" int x = a; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-22 19:16:34 +01:00
checkUninitVar ( " void f(struct blame_entry *ent) \n "
2009-12-22 19:18:02 +01:00
" { \n "
2009-12-22 19:16:34 +01:00
" struct origin *suspect = ent->suspect; \n "
" char hex[41]; \n "
" strcpy(hex, sha1_to_hex(suspect->commit->object.sha1)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-12-23 15:01:23 +01:00
2009-12-29 09:17:07 +01:00
checkUninitVar ( " void foo() \n "
" { \n "
" const std::string s(x()); \n "
" strchr(s.c_str(), ','); \n "
2009-12-23 15:01:23 +01:00
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
}
2010-01-08 21:24:48 +01:00
2010-02-05 17:35:18 +01:00
// strncpy doesn't always 0-terminate..
void uninitvar_strncpy ( )
{
checkUninitVar ( " void f() \n "
" { \n "
" char a[100]; \n "
" strncpy(a, s, 20); \n "
" strncat(a, s, 20); \n "
" } \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (error) Dangerous usage of 'a' (strncpy doesn't always 0-terminate it) \n " , errout . str ( ) ) ;
2010-07-05 12:45:39 +02:00
checkUninitVar ( " void f() \n "
" { \n "
" char a[100]; \n "
" strncpy(a, \" hello \" , 3); \n "
" strncat(a, \" world \" , 20); \n "
" } \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (error) Dangerous usage of 'a' (strncpy doesn't always 0-terminate it) \n " , errout . str ( ) ) ;
2010-07-05 12:45:39 +02:00
checkUninitVar ( " void f() \n "
" { \n "
" char a[100]; \n "
" strncpy(a, \" hello \" , sizeof(a)); \n "
" strncat(a, \" world \" , 20); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-02-05 17:35:18 +01:00
}
2010-01-24 15:23:21 +01:00
std : : string analyseFunctions ( const char code [ ] )
{
// Tokenize..
Tokenizer tokenizer ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
std : : set < std : : string > f ;
2010-05-21 19:35:18 +02:00
const CheckOther checkOther ( ( const Tokenizer * ) 0 , ( const Settings * ) 0 , ( ErrorLogger * ) 0 ) ;
checkOther . analyse ( tokenizer . tokens ( ) , f ) ;
2010-01-24 15:23:21 +01:00
std : : string ret ;
2010-04-02 07:30:58 +02:00
for ( std : : set < std : : string > : : const_iterator it = f . begin ( ) ; it ! = f . end ( ) ; + + it )
2010-04-04 09:17:53 +02:00
ret + = ( ret . empty ( ) ? " " : " " ) + * it ;
2010-01-24 15:23:21 +01:00
return ret ;
}
void uninitvar_func ( )
{
// function analysis..
2010-04-04 09:17:53 +02:00
ASSERT_EQUALS ( " foo " , analyseFunctions ( " void foo(int x) { } " ) ) ;
ASSERT_EQUALS ( " foo " , analyseFunctions ( " void foo(const int &x) { } " ) ) ;
ASSERT_EQUALS ( " foo " , analyseFunctions ( " void foo(int &x) { ++x; } " ) ) ;
ASSERT_EQUALS ( " " , analyseFunctions ( " void foo(int &x) { x = 0; } " ) ) ;
2010-01-24 15:23:21 +01:00
ASSERT_EQUALS ( " " , analyseFunctions ( " void foo(s x) { } " ) ) ;
// function calls..
checkUninitVar ( " void assignOne(int &x) \n "
" { x = 1; } \n "
" \n "
" int f() \n "
2010-01-08 21:24:48 +01:00
" { \n "
2010-01-24 15:23:21 +01:00
" int i; \n "
" assignOne(i); \n "
" return i; \n "
" }; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkUninitVar ( " int f(int (*assign)(int *p)) \n "
" { \n "
" int i; \n "
" (*assign)(&i); \n "
" return i; \n "
2010-01-08 21:24:48 +01:00
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
checkUninitVar ( " int f() \n "
2010-01-08 21:54:24 +01:00
" { \n "
2010-01-24 15:23:21 +01:00
" char s[10]; \n "
" return bar(s); \n "
2010-01-08 21:54:24 +01:00
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
checkUninitVar ( " void f() \n "
2010-01-08 21:24:48 +01:00
" { \n "
2010-01-24 15:23:21 +01:00
" FILE *f; \n "
" fflush(f); \n "
2010-01-08 21:24:48 +01:00
" } \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: f \n " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
checkUninitVar ( " void f() \n "
" { \n "
" Abc *p; \n "
" int sz = sizeof(*p); \n "
" } " ) ;
2010-01-08 21:24:48 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-24 15:23:21 +01:00
checkUninitVar ( " void foo() \n "
" { \n "
" Foo *p; \n "
" x = bar(sizeof(*p)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkUninitVar ( " void foo() \n "
" { \n "
" Foo *p; \n "
" x = bar(p->begin()); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: p \n " , errout . str ( ) ) ;
2010-01-11 22:28:07 +01:00
checkUninitVar ( " int foo(int x) { return x; } \n "
" void f2() \n "
" { \n "
" int x; \n "
" foo(x); \n "
" } \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (error) Uninitialized variable: x \n " , errout . str ( ) ) ;
2010-01-11 22:28:07 +01:00
2010-05-08 19:23:46 +02:00
checkUninitVar ( " void foo(const char *s) \n "
" { \n "
" char *p; \n "
" memcpy(p, s, 100); \n "
" } \n " ) ;
2010-09-17 19:31:45 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: p \n " , errout . str ( ) ) ;
2010-05-08 19:23:46 +02:00
2010-05-09 07:48:52 +02:00
checkUninitVar ( " void foo(const char *s) \n "
" { \n "
" char *p = malloc(100); \n "
" memcpy(p, s, 100); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-23 07:57:57 +01:00
// using uninitialized function pointer..
checkUninitVar ( " void foo() \n "
" { \n "
" void (*f)(); \n "
" f(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Uninitialized variable: f \n " , errout . str ( ) ) ;
2010-09-07 20:25:29 +02:00
// calling noreturn function..
checkUninitVar ( " int foo(int a) { \n "
" int x; \n "
" if (a==1) \n "
" g(); \n " // might be a noreturn function
" else \n "
" x = 3; \n "
" return x; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
checkUninitVar ( " int foo(int a) { \n "
" int x; \n "
" if (a==1) \n "
" g(1); \n " // might be a noreturn function
" else \n "
" x = 3; \n "
" return x; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-09-27 19:26:09 +02:00
checkUninitVar ( " void (*init)(char *str); \n "
" \n "
" char x() { \n "
" char cmd[10]; \n "
" init(cmd); \n "
" return cmd[0]; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-01-11 22:28:07 +01:00
}
2009-06-18 22:26:21 +02:00
void checkOldStylePointerCast ( const char code [ ] )
{
// Tokenize..
2010-04-24 16:46:09 +02:00
Tokenizer tokenizerCpp ;
2009-06-18 22:26:21 +02:00
std : : istringstream istr ( code ) ;
2010-04-24 16:46:09 +02:00
tokenizerCpp . tokenize ( istr , " test.cpp " ) ;
tokenizerCpp . setVarId ( ) ;
Tokenizer tokenizerC ;
std : : istringstream istr2 ( code ) ;
tokenizerC . tokenize ( istr2 , " test.c " ) ;
tokenizerC . setVarId ( ) ;
2009-06-18 22:26:21 +02:00
// Clear the error buffer..
errout . str ( " " ) ;
// Check for redundant code..
Settings settings ;
settings . _checkCodingStyle = true ;
2010-04-24 16:46:09 +02:00
CheckOther checkOtherCpp ( & tokenizerCpp , & settings , this ) ;
checkOtherCpp . warningOldStylePointerCast ( ) ;
CheckOther checkOtherC ( & tokenizerC , & settings , this ) ;
checkOtherC . warningOldStylePointerCast ( ) ;
2009-06-18 22:26:21 +02:00
}
void oldStylePointerCast ( )
{
2009-06-19 12:01:27 +02:00
checkOldStylePointerCast ( " class Base; \n "
" void foo() \n "
" { \n "
" Base * b = (Base *) derived; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (style) C-style pointer casting \n " , errout . str ( ) ) ;
2009-07-20 21:52:27 +02:00
checkOldStylePointerCast ( " class Base; \n "
" void foo() \n "
" { \n "
" Base * b = (const Base *) derived; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (style) C-style pointer casting \n " , errout . str ( ) ) ;
2009-06-19 12:01:27 +02:00
2009-09-24 22:46:08 +02:00
checkOldStylePointerCast ( " class Base; \n "
" void foo() \n "
" { \n "
" Base * b = (const Base *) ( new Derived() ); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (style) C-style pointer casting \n " , errout . str ( ) ) ;
checkOldStylePointerCast ( " class Base; \n "
" void foo() \n "
" { \n "
" Base * b = (const Base *) new Derived(); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (style) C-style pointer casting \n " , errout . str ( ) ) ;
checkOldStylePointerCast ( " class Base; \n "
" void foo() \n "
" { \n "
" Base * b = (const Base *) new short[10]; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (style) C-style pointer casting \n " , errout . str ( ) ) ;
2009-06-18 22:26:21 +02:00
checkOldStylePointerCast ( " class B; \n "
" class A \n "
" { \n "
" virtual void abc(B *) const = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-07-20 21:52:27 +02:00
checkOldStylePointerCast ( " class B; \n "
" class A \n "
" { \n "
" virtual void abc(const B *) const = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-06-18 22:26:21 +02:00
}
2009-10-04 10:05:58 +02:00
void dangerousStrolUsage ( )
{
{
sprintfUsage ( " int f(const char *num) \n "
" { \n "
" return strtol(num, NULL, 1); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Invalid radix in call to strtol or strtoul. Must be 0 or 2-36 \n " , errout . str ( ) ) ;
}
{
sprintfUsage ( " int f(const char *num) \n "
" { \n "
" return strtol(num, NULL, 10); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
}
void testPassedByValue ( const char code [ ] )
{
Tokenizer tokenizer ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
// Clear the error buffer..
errout . str ( " " ) ;
Settings settings ;
2010-04-21 08:38:25 +02:00
settings . _checkCodingStyle = true ;
2009-10-04 10:05:58 +02:00
CheckOther checkOther ( & tokenizer , & settings , this ) ;
checkOther . checkConstantFunctionParameter ( ) ;
}
void passedByValue ( )
{
2009-10-06 23:04:54 +02:00
testPassedByValue ( " void f(const std::string str) {} " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Function parameter 'str' is passed by value. It could be passed by reference instead, to make it faster. \n " , errout . str ( ) ) ;
2009-10-04 10:05:58 +02:00
2009-10-06 23:04:54 +02:00
testPassedByValue ( " class Foo; \n void f(const Foo foo) {} " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (performance) Function parameter 'foo' is passed by value. It could be passed by reference instead, to make it faster. \n " , errout . str ( ) ) ;
2009-10-04 10:05:58 +02:00
2009-10-06 23:04:54 +02:00
testPassedByValue ( " void f(const std::string &str) {} " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-10-04 10:05:58 +02:00
2009-10-06 23:04:54 +02:00
testPassedByValue ( " void f(const std::vector<int> v) {} " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Function parameter 'v' is passed by value. It could be passed by reference instead, to make it faster. \n " , errout . str ( ) ) ;
2009-10-04 10:05:58 +02:00
2009-10-06 23:04:54 +02:00
testPassedByValue ( " void f(const std::vector<std::string> v) {} " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Function parameter 'v' is passed by value. It could be passed by reference instead, to make it faster. \n " , errout . str ( ) ) ;
2009-10-05 10:59:28 +02:00
2009-10-06 23:04:54 +02:00
testPassedByValue ( " void f(const std::vector<int> &v) {} " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-10-05 10:59:28 +02:00
2009-10-06 23:04:54 +02:00
testPassedByValue ( " void f(const std::map<int,int> &v) {} " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-10-05 10:59:28 +02:00
2009-10-06 23:04:54 +02:00
testPassedByValue ( " void f(const std::map<int,int> v) {} " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Function parameter 'v' is passed by value. It could be passed by reference instead, to make it faster. \n " , errout . str ( ) ) ;
2009-10-05 10:59:28 +02:00
2009-10-06 23:04:54 +02:00
testPassedByValue ( " void f(const std::map<std::string,std::string> v) {} " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Function parameter 'v' is passed by value. It could be passed by reference instead, to make it faster. \n " , errout . str ( ) ) ;
2009-10-05 10:59:28 +02:00
2009-10-06 23:04:54 +02:00
testPassedByValue ( " void f(const std::map<int,std::string> v) {} " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Function parameter 'v' is passed by value. It could be passed by reference instead, to make it faster. \n " , errout . str ( ) ) ;
2009-10-05 10:59:28 +02:00
2009-10-06 23:04:54 +02:00
testPassedByValue ( " void f(const std::map<std::string,int> v) {} " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Function parameter 'v' is passed by value. It could be passed by reference instead, to make it faster. \n " , errout . str ( ) ) ;
2009-10-04 10:05:58 +02:00
}
2010-04-02 07:32:03 +02:00
void mathfunctionCall1 ( )
{
2010-04-02 20:42:06 +02:00
// log|log10
2010-04-02 02:19:38 +02:00
check ( " void foo() \n "
" { \n "
" std::cout << log(-2) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value -2 to log() leads to undefined result \n " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << log(-1.) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value -1. to log() leads to undefined result \n " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << log(-1.0) << std::endl; \n "
" } " ) ;
2010-04-02 07:32:03 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value -1.0 to log() leads to undefined result \n " , errout . str ( ) ) ;
2010-04-02 02:19:38 +02:00
check ( " void foo() \n "
" { \n "
" std::cout << log(-0.1) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value -0.1 to log() leads to undefined result \n " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << log(0) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value 0 to log() leads to undefined result \n " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << log(0.) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value 0. to log() leads to undefined result \n " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << log(0.0) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value 0.0 to log() leads to undefined result \n " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << log(1.0E+3) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << log(1.0E-3) << std::endl; \n "
" } " ) ;
2010-04-04 08:01:05 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-02 02:19:38 +02:00
check ( " void foo() \n "
" { \n "
" std::cout << log(1E-3) << std::endl; \n "
" } " ) ;
2010-04-04 08:01:05 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-02 02:19:38 +02:00
2010-07-07 09:03:40 +02:00
check ( " void foo() \n "
" { \n "
" std::string *log(0); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-02 20:42:06 +02:00
// acos
2010-04-02 20:23:37 +02:00
check ( " void foo() \n "
" { \n "
2010-04-04 08:01:05 +02:00
" std::cout << acos(1) << std::endl; \n "
" std::cout << acos(-1) << std::endl; \n "
" std::cout << acos(0.1) << std::endl; \n "
" std::cout << acos(0.0001) << std::endl; \n "
" std::cout << acos(0.01) << std::endl; \n "
" std::cout << acos(1.0E-1) << std::endl; \n "
2010-04-02 20:23:37 +02:00
" std::cout << acos(-1.0E-1) << std::endl; \n "
" std::cout << acos(+1.0E-1) << std::endl; \n "
" std::cout << acos(0.1E-1) << std::endl; \n "
" std::cout << acos(+0.1E-1) << std::endl; \n "
" std::cout << acos(-0.1E-1) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << acos(1.1) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value 1.1 to acos() leads to undefined result \n " , errout . str ( ) ) ;
2010-04-02 02:19:38 +02:00
2010-04-02 20:23:37 +02:00
check ( " void foo() \n "
" { \n "
" std::cout << acos(-1.1) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value -1.1 to acos() leads to undefined result \n " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << acos(-110) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value -110 to acos() leads to undefined result \n " , errout . str ( ) ) ;
2010-04-05 19:35:56 +02:00
// atan2
check ( " void foo() \n "
" { \n "
" std::cout << atan2(1,1) << std::endl; \n "
" std::cout << atan2(-1,-1) << std::endl; \n "
" std::cout << atan2(0.1,1) << std::endl; \n "
" std::cout << atan2(0.0001,100) << std::endl; \n "
" std::cout << atan2(0.01m-1) << std::endl; \n "
" std::cout << atan2(1.0E-1,-3) << std::endl; \n "
" std::cout << atan2(-1.0E-1,+2) << std::endl; \n "
" std::cout << atan2(+1.0E-1,0) << std::endl; \n "
" std::cout << atan2(0.1E-1,3) << std::endl; \n "
" std::cout << atan2(+0.1E-1,1) << std::endl; \n "
" std::cout << atan2(-0.1E-1,8) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << atan2(0,0) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value 0 and 0 to atan2() leads to undefined result \n " , errout . str ( ) ) ;
2010-04-05 20:07:53 +02:00
// fmod
2010-04-05 19:45:33 +02:00
check ( " void foo() \n "
" { \n "
" std::cout << fmod(1.0,0) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value 1.0 and 0 to fmod() leads to undefined result \n " , errout . str ( ) ) ;
2010-04-05 20:07:53 +02:00
check ( " void foo() \n "
" { \n "
" std::cout << fmod(1.0,1) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// pow
check ( " void foo() \n "
" { \n "
" std::cout << pow(0,-10) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value 0 and -10 to pow() leads to undefined result \n " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << pow(0,10) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-05 20:20:20 +02:00
// sqrt
check ( " void foo() \n "
" { \n "
" std::cout << sqrt(-1) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Passing value -1 to sqrt() leads to undefined result \n " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" std::cout << sqrt(1) << std::endl; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-04-05 19:35:56 +02:00
2010-04-02 20:23:37 +02:00
}
2010-04-13 19:30:25 +02:00
void emptyStringTest ( )
{
check ( " void foo() \n "
" { \n "
" if (strlen(str) == 0) \n "
" { \n "
" std::cout << str; \n "
" } \n "
" } \n " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (performance) Empty string test can be simplified to \" *str == ' \\ 0' \" \n " , errout . str ( ) ) ;
2010-04-13 19:30:25 +02:00
check ( " if (!strlen(str)) { } " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Empty string test can be simplified to \" *str == ' \\ 0' \" \n " , errout . str ( ) ) ;
2010-04-13 19:30:25 +02:00
check ( " if (strlen(str) == 0) { } " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Empty string test can be simplified to \" *str == ' \\ 0' \" \n " , errout . str ( ) ) ;
2010-04-13 19:30:25 +02:00
check ( " if (strlen(str)) { } " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Non-empty string test can be simplified to \" *str != ' \\ 0' \" \n " , errout . str ( ) ) ;
2010-04-13 19:30:25 +02:00
check ( " if (strlen(str) > 0) { } " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Non-empty string test can be simplified to \" *str != ' \\ 0' \" \n " , errout . str ( ) ) ;
2010-04-13 19:30:25 +02:00
check ( " if (strlen(str) != 0) { } " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Non-empty string test can be simplified to \" *str != ' \\ 0' \" \n " , errout . str ( ) ) ;
2010-04-13 19:30:25 +02:00
check ( " if (0 != strlen(str)) { } " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Non-empty string test can be simplified to \" *str != ' \\ 0' \" \n " , errout . str ( ) ) ;
2010-04-13 19:30:25 +02:00
check ( " if (0 == strlen(str)) { } " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Empty string test can be simplified to \" *str == ' \\ 0' \" \n " , errout . str ( ) ) ;
2010-04-13 19:30:25 +02:00
check ( " if (0 < strlen(str)) { } " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (performance) Non-empty string test can be simplified to \" *str != ' \\ 0' \" \n " , errout . str ( ) ) ;
2010-04-13 19:30:25 +02:00
}
2010-05-04 08:14:45 +02:00
void fflushOnInputStreamTest ( )
{
check ( " void foo() \n "
" { \n "
" fflush(stdin); \n "
" } \n " ) ;
2010-05-07 08:08:10 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) fflush() called on input stream \" stdin \" may result in undefined behaviour \n " , errout . str ( ) ) ;
2010-05-04 08:14:45 +02:00
check ( " void foo() \n "
" { \n "
" fflush(stdout); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-05-15 14:06:45 +02:00
void sizeofsizeof ( )
{
check ( " void foo() \n "
" { \n "
" int i = sizeof sizeof char; \n "
" } \n " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Suspicious code 'sizeof sizeof ..', most likely there should only be one sizeof. The current code is equivalent to 'sizeof(size_t)'. \n " , errout . str ( ) ) ;
2010-05-15 14:06:45 +02:00
}
2010-06-15 08:45:46 +02:00
2010-08-06 22:57:10 +02:00
void sizeofCalculation ( )
{
check ( " sizeof(a+b) " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (warning) Found calculation inside sizeof() \n " , errout . str ( ) ) ;
2010-08-07 10:12:39 +02:00
check ( " sizeof(-a) " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " sizeof(void * const) " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-08-06 22:57:10 +02:00
}
2010-06-30 09:10:30 +02:00
void switchRedundantAssignmentTest ( )
{
check ( " void foo() \n "
" { \n "
" int y = 1; \n "
" switch (a) \n "
" { \n "
" case 2: \n "
" y = 2; \n "
" case 3: \n "
" y = 3; \n "
" } \n "
" } \n " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (warning) Redundant assignment of \" y \" in switch \n " , errout . str ( ) ) ;
2010-06-30 09:10:30 +02:00
check ( " void foo() \n "
" { \n "
" int y = 1; \n "
" switch (a) \n "
" { \n "
" case 2: \n "
" { \n "
" y = 2; \n "
" } \n "
" case 3: \n "
" y = 3; \n "
" } \n "
" } \n " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (warning) Redundant assignment of \" y \" in switch \n " , errout . str ( ) ) ;
2010-06-30 09:10:30 +02:00
check ( " void foo() \n "
" { \n "
" int y = 1; \n "
" switch (a) \n "
" { \n "
" case 2: \n "
" y = 2; \n "
" case 3: \n "
" if (x) \n "
" { \n "
" y = 3; \n "
" } \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" int y = 1; \n "
" switch (a) \n "
" { \n "
" case 2: \n "
" { \n "
" y = 2; \n "
" if (y) \n "
" printf( \" %d \" , y); \n "
" } \n "
" case 3: \n "
" y = 3; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" int x = a; \n "
" int y = 1; \n "
" switch (x) \n "
" { \n "
" case 2: \n "
" x = 2; \n "
" case 3: \n "
" y = 3; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" int y = 1; \n "
" switch (x) \n "
" { \n "
" case 2: \n "
" { \n "
" int y = 2; \n "
" } \n "
" case 3: \n "
" y = 3; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" int y = 1; \n "
" switch (x) \n "
" { \n "
" case 2: \n "
" y = 2; \n "
" break; \n "
" case 3: \n "
" y = 3; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-09-04 14:24:45 +02:00
check ( " void foo() \n "
" { \n "
" int y = 1; \n "
" while(xyz()) { \n "
" switch (x) \n "
" { \n "
" case 2: \n "
" y = 2; \n "
" continue; \n "
" case 3: \n "
" y = 3; \n "
" } \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-06-30 09:10:30 +02:00
check ( " void foo() \n "
" { \n "
" int y = 1; \n "
" switch (x) \n "
" { \n "
" case 2: \n "
" y = 2; \n "
" printf( \" %d \" , y); \n "
" case 3: \n "
" y = 3; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" int y = 1; \n "
" switch (x) \n "
" { \n "
" case 2: \n "
" y = 2; \n "
" bar(); \n "
" case 3: \n "
" y = 3; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-14 15:15:12 +02:00
2010-08-15 06:28:22 +02:00
void selfAssignment ( )
{
check ( " void foo() \n "
" { \n "
" int x = 1; \n "
" x = x; \n "
" return 0; \n "
" } \n " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (warning) Redundant assignment of \" x \" to itself \n " , errout . str ( ) ) ;
2010-08-15 06:28:22 +02:00
check ( " void foo() \n "
" { \n "
" int x = x; \n "
" return 0; \n "
" } \n " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Redundant assignment of \" x \" to itself \n " , errout . str ( ) ) ;
2010-08-15 06:28:22 +02:00
check ( " void foo() \n "
" { \n "
" std::string var = var = \" test \" ; \n "
" return 0; \n "
" } \n " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Redundant assignment of \" var \" to itself \n " , errout . str ( ) ) ;
2010-08-15 06:28:22 +02:00
check ( " void foo() \n "
" { \n "
" int x = 1; \n "
" x = x + 1; \n "
" return 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-14 15:15:12 +02:00
void testScanf1 ( )
{
check ( " #include <stdio.h> \n "
" int main(int argc, char **argv) \n "
" { \n "
" int a, b; \n "
" FILE *file = fopen( \" test \" , \" r \" ); \n "
" b = fscanf(file, \" aa %ds \" , &a); \n "
" c = scanf( \" aa %ds \" , &a); \n "
" b = fscanf(file, \" aa%%ds \" , &a); \n "
" fclose(file); \n "
" return b; \n "
" } \n " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (warning) scanf without field width limits can crash with huge input data \n "
" [test.cpp:7]: (warning) scanf without field width limits can crash with huge input data \n " , errout . str ( ) ) ;
2010-08-14 15:15:12 +02:00
}
void testScanf2 ( )
{
check ( " #include <stdio.h> \n "
" int main(int argc, char **argv) \n "
" { \n "
" int a, b; \n "
" FILE *file = fopen( \" test \" , \" r \" ); \n "
" b = fscanf(file, \" aa%%%ds \" , &a); \n "
" c = scanf( \" aa %%%ds \" , &a); \n "
" b = fscanf(file, \" aa%%ds \" , &a); \n "
" fclose(file); \n "
" return b; \n "
" } \n " ) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (warning) scanf without field width limits can crash with huge input data \n "
" [test.cpp:7]: (warning) scanf without field width limits can crash with huge input data \n " , errout . str ( ) ) ;
2010-08-14 15:15:12 +02:00
}
2010-10-01 17:23:22 +02:00
void trac1132 ( )
{
errout . str ( " " ) ;
std : : istringstream code ( " #include <iostream> \n "
" class Lock \n "
" { \n "
" public: \n "
" Lock(int i) \n "
" { \n "
" std::cout << \" Lock \" << i << std::endl; \n "
" } \n "
" ~Lock() \n "
" { \n "
" std::cout << \" ~Lock \" << std::endl; \n "
" } \n "
" }; \n "
" int main() \n "
" { \n "
" Lock(123); \n "
" std::cout << \" hello \" << std::endl; \n "
" return 0; \n "
" } \n "
) ;
Tokenizer tokenizer ;
tokenizer . tokenize ( code , " trac1132.cpp " ) ;
tokenizer . simplifyTokenList ( ) ;
Settings settings ;
CheckOther checkOther ( & tokenizer , & settings , this ) ;
checkOther . checkMisusedScopedObject ( ) ;
ASSERT_EQUALS ( " [trac1132.cpp:16]: (error) instance of \" Lock \" object destroyed immediately \n " , errout . str ( ) ) ;
}
void testMisusedScopeObjectDoesNotPickFunction ( )
{
check ( " int main ( ) \n "
" { \n "
" CouldBeFunction ( 123 ) ; \n "
" return 0 ; \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
void testMisusedScopeObjectPicksClass ( )
{
check ( " class NotAFunction ; \n "
" int function ( ) \n "
" { \n "
" NotAFunction ( 123 ); \n "
" return 0 ; \n "
" } \n "
) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) instance of \" NotAFunction \" object destroyed immediately \n " , errout . str ( ) ) ;
}
void testMisusedScopeObjectPicksStruct ( )
{
check ( " struct NotAClass; \n "
" bool func ( ) \n "
" { \n "
" NotAClass ( 123 ) ; \n "
" return true ; \n "
" } \n "
) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) instance of \" NotAClass \" object destroyed immediately \n " , errout . str ( ) ) ;
}
void testMisusedScopeObjectDoesNotPickIf ( )
{
check ( " bool func( int a , int b , int c ) \n "
" { \n "
" if ( a > b ) return c == a ; \n "
" return b == a ; \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
void testMisusedScopeObjectDoesNotPickConstructorDeclaration ( )
{
check ( " class Something : public SomthingElse \n "
" { \n "
" public: \n "
" ~Something ( ) ; \n "
" Something ( ) ; \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-10-02 10:43:12 +02:00
void testMisusedScopeObjectDoesNotPickFunctor ( )
{
check ( " \n "
" #include <algorithm> \n "
" \n "
" class IncrementFunctor \n "
" { \n "
" public: \n "
" void operator()(int &i) \n "
" { \n "
" ++i; \n "
" } \n "
" }; \n "
" \n "
" int main() \n "
" { \n "
2010-10-02 13:16:50 +02:00
" int a = 1; \n "
" IncrementFunctor()(a); \n "
" return a; \n "
2010-10-02 10:43:12 +02:00
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-10-02 12:12:52 +02:00
2010-10-02 14:59:04 +02:00
void testMisusedScopeObjectDoesNotPickLocalClassConstructors ( )
2010-10-02 12:12:52 +02:00
{
check ( " void f() { \n "
" class Foo { \n "
" Foo() { } \n "
2010-10-02 14:59:04 +02:00
" Foo(int a) { } \n "
" Foo(int a, int b) { } \n "
2010-10-02 12:12:52 +02:00
" }; \n "
2010-10-02 14:59:04 +02:00
" Foo(); \n "
2010-10-02 12:12:52 +02:00
" } \n "
) ;
2010-10-02 14:59:04 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (error) instance of \" Foo \" object destroyed immediately \n " , errout . str ( ) ) ;
2010-10-02 12:12:52 +02:00
}
2010-10-02 12:26:29 +02:00
void testMisusedScopeObjectDoesNotPickUsedObject ( )
{
check ( " struct Foo { \n "
" void bar() { \n "
" } \n "
" }; \n "
" \n "
" void fn() { \n "
" Foo().bar(); \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-10-03 23:16:11 +02:00
2010-10-13 11:31:41 +02:00
void trac2084 ( )
{
check ( " #include <signal.h> \n "
" \n "
" void f() \n "
" { \n "
" struct sigaction sa; \n "
" \n "
" { sigaction(SIGHUP, &sa, 0); }; \n "
" { sigaction(SIGINT, &sa, 0); }; \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-10-03 23:16:11 +02:00
void trac2071 ( )
{
check ( " void f() { \n "
2010-10-05 20:54:13 +02:00
" struct AB { \n "
" AB(int a) { } \n "
" }; \n "
" \n "
" const AB ab[3] = { AB(0), AB(1), AB(2) }; \n "
" } \n "
) ;
2010-10-03 23:16:11 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-10-10 22:05:06 +02:00
void assignmentInAssert ( )
{
check ( " void f() { \n "
" int a = 0; \n "
" assert(a = 2); \n "
" return a; \n "
" } \n "
) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Assert statement modifies 'a'. If the modification is needed in release builds there is a bug. \n " , errout . str ( ) ) ;
2010-10-10 22:05:06 +02:00
check ( " void f() { \n "
" int a = 0; \n "
" assert(a == 2); \n "
" return a; \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" int a = 0; \n "
" int b = 0; \n "
" assert(a == 2 && b = 1); \n "
" return a; \n "
" } \n "
) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (warning) Assert statement modifies 'b'. If the modification is needed in release builds there is a bug. \n " , errout . str ( ) ) ;
2010-10-10 22:05:06 +02:00
check ( " void f() { \n "
" int a = 0; \n "
" assert(a += 2); \n "
" return a; \n "
" } \n "
) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Assert statement modifies 'a'. If the modification is needed in release builds there is a bug. \n " , errout . str ( ) ) ;
2010-10-10 22:05:06 +02:00
check ( " void f() { \n "
" int a = 0; \n "
" assert(a *= 2); \n "
" return a; \n "
" } \n "
) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Assert statement modifies 'a'. If the modification is needed in release builds there is a bug. \n " , errout . str ( ) ) ;
2010-10-10 22:05:06 +02:00
check ( " void f() { \n "
" int a = 0; \n "
" assert(a -= 2); \n "
" return a; \n "
" } \n "
) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Assert statement modifies 'a'. If the modification is needed in release builds there is a bug. \n " , errout . str ( ) ) ;
2010-10-10 22:05:06 +02:00
check ( " void f() { \n "
" int a = 0; \n "
" assert(a --); \n "
" return a; \n "
" } \n "
) ;
2010-10-17 14:41:00 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Assert statement modifies 'a'. If the modification is needed in release builds there is a bug. \n " , errout . str ( ) ) ;
2010-10-10 22:05:06 +02:00
}
2010-10-25 03:14:21 +02:00
void incorrectLogicOperator ( )
{
check ( " void f() { \n "
" if ((x != 1) || (x != 3)) \n "
" a++; \n "
" } \n "
) ;
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Mutual exclusion over || always evaluates to true. Did you intend to use && instead? \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" if (x != 1 || x != 3) \n "
" a++; \n "
" } \n "
) ;
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Mutual exclusion over || always evaluates to true. Did you intend to use && instead? \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" if (1 != x || 3 != x) \n "
" a++; \n "
" } \n "
) ;
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Mutual exclusion over || always evaluates to true. Did you intend to use && instead? \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" if (x != 1 || y != 1) \n "
" a++; \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" if ((y == 1) && (x != 1) || (x != 3)) \n "
" a++; \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" if ((x != 1) || (x != 3) && (y == 1)) \n "
" a++; \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" if ((x != 1) && (x != 3)) \n "
" a++; \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" if ((x == 1) || (x == 3)) \n "
" a++; \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" if ((x != 1) || (y != 3)) \n "
" a++; \n "
" } \n "
) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2008-12-19 22:15:18 +01:00
} ;
2009-01-05 16:49:57 +01:00
REGISTER_TEST ( TestOther )
2010-10-01 12:52:16 +02:00