2010-10-31 11:51:25 +01:00
/*
* Cppcheck - A tool for static C / C + + code analysis
2015-01-03 12:14:58 +01:00
* Copyright ( C ) 2007 - 2015 Daniel Marjamäki and Cppcheck team .
2010-10-31 11:51:25 +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
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "tokenize.h"
# include "checknullpointer.h"
# include "testsuite.h"
2015-01-29 06:07:48 +01:00
# include <tinyxml2.h>
2010-10-31 11:51:25 +01:00
2011-10-13 20:53:06 +02:00
class TestNullPointer : public TestFixture {
2010-10-31 11:51:25 +01:00
public :
2014-11-20 14:20:09 +01:00
TestNullPointer ( ) : TestFixture ( " TestNullPointer " ) {
2013-08-07 16:27:37 +02:00
}
2010-10-31 11:51:25 +01:00
private :
2014-03-24 09:59:05 +01:00
Settings settings ;
2010-10-31 11:51:25 +01:00
2014-11-20 14:20:09 +01:00
void run ( ) {
2015-01-29 06:07:48 +01:00
// Load std.cfg configuration
{
const char xmldata [ ] = " <?xml version= \" 1.0 \" ?> \n "
" <def> \n "
" <function name= \" strcpy \" > \n "
" <arg nr= \" 1 \" ><not-null/></arg> \n "
" <arg nr= \" 2 \" ><not-null/></arg> \n "
" </function> \n "
" </def> " ;
tinyxml2 : : XMLDocument doc ;
doc . Parse ( xmldata , sizeof ( xmldata ) ) ;
settings . library . load ( doc ) ;
}
2014-03-24 09:59:05 +01:00
2011-10-09 15:09:02 +02:00
TEST_CASE ( nullpointerAfterLoop ) ;
2010-10-31 11:51:25 +01:00
TEST_CASE ( nullpointer1 ) ;
TEST_CASE ( nullpointer2 ) ;
2010-11-04 18:18:19 +01:00
TEST_CASE ( structDerefAndCheck ) ; // dereferencing struct and then checking if it's null
TEST_CASE ( pointerDerefAndCheck ) ;
2010-10-31 11:51:25 +01:00
TEST_CASE ( nullpointer5 ) ; // References should not be checked
2010-12-26 13:38:16 +01:00
TEST_CASE ( nullpointerExecutionPaths ) ;
TEST_CASE ( nullpointerExecutionPathsLoop ) ;
2010-10-31 11:51:25 +01:00
TEST_CASE ( nullpointer7 ) ;
TEST_CASE ( nullpointer9 ) ;
2011-05-28 05:30:19 +02:00
TEST_CASE ( nullpointer10 ) ;
2011-06-04 04:16:08 +02:00
TEST_CASE ( nullpointer11 ) ; // ticket #2812
2011-10-16 12:54:58 +02:00
TEST_CASE ( nullpointer12 ) ; // ticket #2470
2012-01-28 08:06:03 +01:00
TEST_CASE ( nullpointer15 ) ; // #3560 (fp: return p ? f(*p) : f(0))
2012-02-13 19:46:45 +01:00
TEST_CASE ( nullpointer16 ) ; // #3591
2012-03-07 20:31:23 +01:00
TEST_CASE ( nullpointer17 ) ; // #3567
2012-04-01 15:56:48 +02:00
TEST_CASE ( nullpointer18 ) ; // #1927
2012-05-16 09:56:39 +02:00
TEST_CASE ( nullpointer19 ) ; // #3811
2012-05-31 18:41:00 +02:00
TEST_CASE ( nullpointer20 ) ; // #3807 (fp: return p ? (p->x() || p->y()) : z)
2012-09-23 09:20:16 +02:00
TEST_CASE ( nullpointer21 ) ; // #4038 (fp: if (x) p=q; else return;)
2013-03-19 08:47:05 +01:00
TEST_CASE ( nullpointer23 ) ; // #4665 (false positive)
2013-10-20 13:37:36 +02:00
TEST_CASE ( nullpointer24 ) ; // #5082 fp: chained assignment
2014-03-26 12:17:27 +01:00
TEST_CASE ( nullpointer25 ) ; // #5061
2014-03-27 19:16:30 +01:00
TEST_CASE ( nullpointer26 ) ; // #3589
2015-01-05 14:54:24 +01:00
TEST_CASE ( nullpointer_addressOf ) ; // address of
2014-03-28 10:06:24 +01:00
TEST_CASE ( nullpointerSwitch ) ; // #2626
2013-04-03 10:27:08 +02:00
TEST_CASE ( nullpointer_cast ) ; // #4692
2012-04-30 12:36:41 +02:00
TEST_CASE ( nullpointer_castToVoid ) ; // #3771
2011-10-12 22:11:27 +02:00
TEST_CASE ( pointerCheckAndDeRef ) ; // check if pointer is null and then dereference it
TEST_CASE ( nullConstantDereference ) ; // Dereference NULL constant
TEST_CASE ( gcc_statement_expression ) ; // Don't crash
2011-06-26 21:46:33 +02:00
TEST_CASE ( snprintf_with_zero_size ) ;
TEST_CASE ( snprintf_with_non_zero_size ) ;
2011-10-12 22:11:27 +02:00
TEST_CASE ( printf_with_invalid_va_argument ) ;
TEST_CASE ( scanf_with_invalid_va_argument ) ;
2011-10-23 23:36:57 +02:00
TEST_CASE ( nullpointer_in_return ) ;
2011-11-04 09:49:49 +01:00
TEST_CASE ( nullpointer_in_typeid ) ;
2011-11-07 21:10:21 +01:00
TEST_CASE ( nullpointer_in_for_loop ) ;
2011-11-13 22:35:13 +01:00
TEST_CASE ( nullpointerDelete ) ;
2011-11-23 21:19:54 +01:00
TEST_CASE ( nullpointerExit ) ;
2012-01-25 15:16:22 +01:00
TEST_CASE ( nullpointerStdString ) ;
2012-03-16 17:24:03 +01:00
TEST_CASE ( nullpointerStdStream ) ;
2011-12-25 17:01:45 +01:00
TEST_CASE ( functioncall ) ;
2013-07-15 21:57:58 +02:00
TEST_CASE ( functioncalllibrary ) ; // use Library to parse function call
2012-11-21 08:56:17 +01:00
TEST_CASE ( functioncallDefaultArguments ) ;
2013-10-12 10:50:59 +02:00
TEST_CASE ( nullpointer_internal_error ) ; // #5080
2010-10-31 11:51:25 +01:00
}
2014-11-20 14:20:09 +01:00
void check ( const char code [ ] , bool inconclusive = false , const char filename [ ] = " test.cpp " , bool verify = true ) {
2010-10-31 11:51:25 +01:00
// Clear the error buffer..
errout . str ( " " ) ;
2013-02-02 15:46:29 +01:00
settings . addEnabled ( " warning " ) ;
2011-10-09 15:09:02 +02:00
settings . inconclusive = inconclusive ;
2014-01-12 19:27:26 +01:00
2010-12-01 18:00:55 +01:00
// Tokenize..
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
2012-08-25 12:00:25 +02:00
if ( ! tokenizer . tokenize ( istr , filename ) )
2012-08-12 12:01:24 +02:00
return ;
2010-12-01 18:00:55 +01:00
// Check for redundant code..
2010-10-31 11:51:25 +01:00
CheckNullPointer checkNullPointer ( & tokenizer , & settings , this ) ;
checkNullPointer . nullPointer ( ) ;
2013-04-15 19:00:15 +02:00
const std : : string str1 ( tokenizer . tokens ( ) - > stringifyList ( 0 , true ) ) ;
2013-12-30 17:45:28 +01:00
tokenizer . simplifyTokenList2 ( ) ;
2013-04-15 19:00:15 +02:00
const std : : string str2 ( tokenizer . tokens ( ) - > stringifyList ( 0 , true ) ) ;
if ( verify & & str1 ! = str2 )
2014-09-13 12:59:32 +02:00
warnUnsimplified ( str1 , str2 ) ;
2013-04-15 19:00:15 +02:00
2010-10-31 11:51:25 +01:00
checkNullPointer . nullConstantDereference ( ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointerAfterLoop ( ) {
2010-10-31 11:51:25 +01:00
check ( " int foo(const Token *tok) \n "
" { \n "
" while (tok); \n "
" tok = tok->next(); \n "
2014-09-04 17:52:14 +02:00
" } " , true ) ;
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:3]: (warning, inconclusive) Possible null pointer dereference: tok - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
2011-03-28 19:27:07 +02:00
// #2681
2011-10-18 19:34:14 +02:00
{
const char code [ ] = " void foo(const Token *tok) \n "
" { \n "
" while (tok && tok->str() == \" = \" ) \n "
" tok = tok->next(); \n "
" \n "
" if (tok->str() != \" ; \" ) \n "
" ; \n "
" } \n " ;
check ( code , false ) ; // inconclusive=false => no error
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( code , true ) ; // inconclusive=true => error
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:6] -> [test.cpp:3]: (warning, inconclusive) Possible null pointer dereference: tok - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-10-18 19:34:14 +02:00
}
2011-03-28 19:27:07 +02:00
2010-10-31 11:51:25 +01:00
check ( " 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 "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:5]: (warning) Possible null pointer dereference: tok - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
check ( " 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 "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " 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 "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " 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 "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " 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 "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-09 15:09:02 +02:00
// dereference in outer scope..
2014-06-22 10:02:14 +02:00
check ( " void foo(int x, const Token *tok) { \n "
" if (x == 123) { \n "
" while (tok) tok = tok->next(); \n "
" } \n "
" tok->str(); \n "
" } \n " ) ;
TODO_ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:3]: (warning, inconclusive) Possible null pointer dereference: tok - otherwise it is redundant to check it against null. \n " , " " , errout . str ( ) ) ;
2011-10-23 23:36:57 +02:00
check ( " int foo(const Token *tok) \n "
" { \n "
" while (tok){;} \n "
" } \n " , true ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " int foo(const Token *tok) \n "
" { \n "
" while (tok){;} \n "
" char a[2] = {0,0}; \n "
" } \n " , true ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-09 15:09:02 +02:00
}
2014-11-20 14:20:09 +01:00
void nullpointer1 ( ) {
2010-10-31 11:51:25 +01:00
// ticket #1923 - no false positive when using else if
check ( " 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 "
2013-04-15 19:00:15 +02:00
" } " , false , " test.cpp " , false ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// ticket #2134 - sizeof doesn't dereference
check ( " void f() { \n "
" int c = 1; \n "
" int *list = NULL; \n "
" sizeof(*list); \n "
" if (!list) \n "
" ; \n "
2013-04-15 19:00:15 +02:00
" } " , true , " test.cpp " , false ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-11-29 20:19:31 +01:00
// ticket #2245 - sizeof doesn't dereference
check ( " void f(Bar *p) { \n "
" if (!p) { \n "
" int sz = sizeof(p->x); \n "
" } \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2010-11-29 20:19:31 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
}
2014-11-20 14:20:09 +01:00
void nullpointer2 ( ) {
2010-10-31 11:51:25 +01:00
// Null pointer dereference can only happen with pointers
check ( " void foo() \n "
" { \n "
" Fred fred; \n "
" while (fred); \n "
" fred.hello(); \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
// Dereferencing a struct and then checking if it is null
// This is checked by this function:
// CheckOther::nullPointerStructByDeRefAndChec
2014-11-20 14:20:09 +01:00
void structDerefAndCheck ( ) {
2010-10-31 11:51:25 +01:00
// errors..
check ( " void foo(struct ABC *abc) \n "
" { \n "
" int a = abc->a; \n "
" if (!abc) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:4]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
2011-02-19 21:01:38 +01:00
check ( " void foo(struct ABC *abc) { \n "
2010-10-31 11:51:25 +01:00
" bar(abc->a); \n "
2014-05-22 19:48:00 +02:00
" bar(x, abc->a); \n "
" bar(x, y, abc->a); \n "
2010-10-31 11:51:25 +01:00
" if (!abc) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2014-05-22 19:48:00 +02:00
ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:5]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n "
" [test.cpp:3] -> [test.cpp:5]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n "
" [test.cpp:4] -> [test.cpp:5]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-02-19 21:01:38 +01:00
2011-02-20 19:45:34 +01:00
check ( " void foo(ABC *abc) { \n "
" if (abc->a == 3) { \n "
" return; \n "
" } \n "
" if (abc) {} \n "
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:5]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-02-20 19:45:34 +01:00
2011-08-01 21:57:23 +02:00
check ( " void f(ABC *abc) { \n "
" if (abc->x == 0) { \n "
" return; \n "
" } \n "
" if (!abc); \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:5]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-08-01 21:57:23 +02:00
2011-02-19 21:01:38 +01:00
// TODO: False negative if member of member is dereferenced
check ( " void foo(ABC *abc) { \n "
" abc->next->a = 0; \n "
" if (abc->next) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
TODO_ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:3]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n " , " " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
2011-02-19 21:10:31 +01:00
check ( " void foo(ABC *abc) { \n "
" abc->a = 0; \n "
" if (abc && abc->b == 0) \n "
" ; \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:3]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-02-19 21:10:31 +01:00
2010-10-31 11:51:25 +01:00
// ok dereferencing in a condition
check ( " void foo(struct ABC *abc) \n "
" { \n "
" if (abc && abc->a); \n "
" if (!abc) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-12-02 06:11:55 +01:00
check ( " void f(struct ABC *abc) { \n "
" int x = abc && a(abc->x); \n "
" if (abc) { } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
// ok to use a linked list..
check ( " void foo(struct ABC *abc) \n "
" { \n "
" abc = abc->next; \n "
" if (!abc) \n "
" ; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-12-08 19:30:14 +01:00
check ( " void f(struct ABC *abc) { \n "
" abc = (ABC *)(abc->_next); \n "
" if (abc) { } "
2013-04-15 19:00:15 +02:00
" } " , true , " test.cpp " , false ) ;
2011-12-08 19:30:14 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
// reassign struct..
check ( " void foo(struct ABC *abc) \n "
" { \n "
" int a = abc->a; \n "
" abc = abc->next; \n "
" if (!abc) \n "
" ; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo(struct ABC *abc) \n "
" { \n "
" int a = abc->a; \n "
" f(&abc); \n "
" if (!abc) \n "
" ; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// goto..
check ( " void foo(struct ABC *abc) \n "
" { \n "
" int a; \n "
" if (!abc) \n "
" goto out; "
" a = abc->a; \n "
" return; \n "
" out: \n "
" if (!abc) \n "
" ; \n "
2013-04-15 19:00:15 +02:00
" } " , false , " test.cpp " , false ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// loops..
check ( " void foo(struct ABC *abc) \n "
" { \n "
" int a = abc->a; "
" do \n "
" { \n "
" if (abc) \n "
" abc = abc->next; \n "
" --a; \n "
" } \n "
" while (a > 0); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " 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 "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// dynamic_cast..
check ( " void foo(ABC *abc) \n "
" { \n "
" int a = abc->a; \n "
" if (!dynamic_cast<DEF *>(abc)) \n "
" ; \n "
2013-04-15 19:00:15 +02:00
" } " , false , " test.cpp " , false ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-03-12 15:02:06 +01:00
// #2641 - global pointer, function call
check ( " ABC *abc; \n "
" void f() { \n "
" abc->a = 0; \n "
" do_stuff(); \n "
" if (abc) { } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-03-12 17:42:58 +01:00
2011-03-12 20:57:19 +01:00
check ( " Fred *fred; \n "
" void f() { \n "
" fred->foo(); \n "
" if (fred) { } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-03-12 17:42:58 +01:00
// #2641 - local pointer, function call
check ( " void f() { \n "
" ABC *abc; \n "
" abc->a = 0; \n "
" do_stuff(); \n "
" if (abc) { } \n "
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:5]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-03-12 18:27:19 +01:00
// #2641 - local pointer, function call
check ( " void f(ABC *abc) { \n "
" abc->a = 0; \n "
" do_stuff(); \n "
" if (abc) { } \n "
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:4]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-03-28 17:28:21 +02:00
// #2691 - switch/break
check ( " void f(ABC *abc) { \n "
" switch ( x ) { \n "
" case 14: \n "
" sprintf(buf, \" %d \" , abc->a); \n "
" break; \n "
" case 15: \n "
" if ( abc ) {} \n "
" break; \n "
" } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-07 21:08:21 +02:00
// #3128
check ( " void f(ABC *abc) { \n "
" x(!abc || y(abc->a)); \n "
" if (abc) {} \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-30 17:59:38 +01:00
2013-10-22 10:47:48 +02:00
check ( " void f(ABC *abc) { \n "
" x(def || !abc || y(def, abc->a)); \n "
" if (abc) {} \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(ABC *abc) { \n "
" x(abc && y(def, abc->a)); \n "
" if (abc) {} \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(ABC *abc) { \n "
" x(def && abc && y(def, abc->a)); \n "
" if (abc) {} \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-30 17:59:38 +01:00
// #3228 - calling function with null object
{
const char code [ ] = " void f(Fred *fred) { \n "
" fred->x(); \n "
" if (fred) { } \n "
" } " ;
check ( code ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( code , true ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:3]: (warning, inconclusive) Possible null pointer dereference: fred - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-10-30 17:59:38 +01:00
}
2011-12-18 13:33:23 +01:00
2014-01-03 18:53:37 +01:00
// #3425 - false positives when there are macros
2011-12-18 13:33:23 +01:00
check ( " void f(struct FRED *fred) { \n "
" fred->x = 0; \n "
" $if(!fred){} \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
}
// Dereferencing a pointer and then checking if it is null
2014-11-20 14:20:09 +01:00
void pointerDerefAndCheck ( ) {
2010-10-31 11:51:25 +01:00
// errors..
check ( " void foo(int *p) \n "
" { \n "
" *p = 0; \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:4]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
2011-08-02 11:20:09 +02:00
check ( " void foo(int *p) \n "
" { \n "
" *p = 0; \n "
" if (p) { } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:4]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-08-02 11:20:09 +02:00
2011-08-02 17:04:07 +02:00
check ( " void foo(int *p) \n "
" { \n "
" *p = 0; \n "
" if (p || q) { } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:4]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-08-02 17:04:07 +02:00
2010-10-31 11:51:25 +01:00
check ( " void foo(int *p) \n "
" { \n "
" bar(*p); \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:4]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
2011-07-31 14:07:35 +02:00
check ( " void foo(char *p) \n "
" { \n "
" strcpy(p, \" abc \" ); \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:4]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-07-31 14:07:35 +02:00
2011-08-02 17:20:13 +02:00
check ( " void foo(char *p) \n "
" { \n "
" if (*p == 0) { } \n "
" if (!p) { } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2014-01-12 19:51:05 +01:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:4]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-08-02 17:20:13 +02:00
2010-10-31 11:51:25 +01:00
// no error
check ( " void foo() \n "
" { \n "
" int *p; \n "
" f(&p); \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" int **p = f(); \n "
" if (!p) \n "
" ; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo(int *p) \n "
" { \n "
" if (x) \n "
" p = 0; \n "
" else \n "
" *p = 0; \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo(int x) \n "
" { \n "
" int a = 2 * x; "
" if (x == 0) \n "
" ; \n "
2015-01-31 20:12:02 +01:00
" } " , true , " test.cpp " , false ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo(int *p) \n "
" { \n "
" int var1 = p ? *p : 0; \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-02 19:27:18 +02:00
check ( " void foo(int *p) \n "
" { \n "
" int var1 = x ? *p : 5; \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2014-05-22 19:48:00 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:4]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-10-02 19:27:18 +02:00
2013-05-03 16:18:44 +02:00
// while
check ( " void f(int *p) { \n "
" *p = 0; \n "
" while (p) { p = 0; } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p) { \n "
" *p = 0; \n "
" while (p) { } \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:3]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-10-02 19:27:18 +02:00
// Ticket #3125
check ( " void foo(ABC *p) \n "
" { \n "
" int var1 = p ? (p->a) : 0; \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-10-02 19:27:18 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo(ABC *p) \n "
" { \n "
" int var1 = p ? (1 + p->a) : 0; \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-10-02 19:27:18 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-01-21 19:38:59 +01:00
check ( " void f() { \n "
" int * a=0; \n "
" if (!a) {}; \n "
" int c = a ? 0 : 1; \n "
2013-04-15 19:00:15 +02:00
" } \n " , true , " test.cpp " , false ) ;
2013-01-21 19:38:59 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// #3686
check ( " void f() { \n "
" int * a=0; \n "
" if (!a) {}; \n "
" int c = a ? b : b+1; \n "
2013-04-15 19:00:15 +02:00
" } \n " , true , " test.cpp " , false ) ;
2013-01-21 19:38:59 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" int * a=0; \n "
" if (!a) {}; \n "
" int c = (a) ? b : b+1; \n "
2013-04-15 19:00:15 +02:00
" } \n " , true , " test.cpp " , false ) ;
2013-01-21 19:38:59 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
check ( " void foo(P *p) \n "
" { \n "
" while (p) \n "
" if (p->check()) \n "
" break; \n "
" else \n "
" p = p->next(); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-31 19:48:58 +01:00
check ( " void f(Document *doc) { \n "
" int x = doc && doc->x; \n "
" if (!doc) { \n "
" return; \n "
" } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-11-04 18:18:19 +01:00
2011-10-07 21:08:21 +02:00
// #3128 - false positive
check ( " void f(int *p) { \n "
" assert(!p || (*p<=6)); \n "
" if (p) { *p = 0; } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p) { \n "
" assert(p && (*p<=6)); \n "
" if (p) { *p = 0; } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-08 12:58:10 +02:00
check ( " void f(int *p) { \n "
" *p = 12; \n "
" assert(p && (*p<=6)); \n "
" if (p) { *p = 0; } \n "
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:4]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-10-08 12:58:10 +02:00
2010-11-04 18:18:19 +01:00
check ( " void foo(x *p) \n "
" { \n "
" p = p->next; \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-11-04 18:18:19 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-17 21:09:12 +01:00
check ( " void foo(x *p) \n "
" { \n "
" p = bar(p->next); \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-12-17 21:09:12 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-01-08 17:16:52 +01:00
2011-06-21 18:45:30 +02:00
check ( " void foo(x *p) \n "
" { \n "
" p = aa->bar(p->next); \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-06-21 18:45:30 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-05-01 07:06:14 +02:00
check ( " void foo(x *p) \n "
" { \n "
" p = *p2 = p->next; \n "
" if (!p) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-05-01 07:06:14 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-01-08 17:16:52 +01:00
check ( " void foo(struct ABC *abc) \n "
" { \n "
" abc = abc ? abc->next : 0; \n "
" if (!abc) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-01-08 17:16:52 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-01-10 19:57:26 +01:00
2013-01-29 17:12:14 +01:00
check ( " void f(struct ABC *abc) { \n " // #4523
" abc = (*abc).next; \n "
" if (abc) { } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-01-30 16:52:12 +01:00
check ( " void f(struct ABC *abc) { \n " // #4523
" abc = (*abc->ptr); \n "
" if (abc) { } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-03-29 18:45:32 +02:00
check ( " int f(Item *item) { \n "
" x = item ? ab(item->x) : 0; \n "
" if (item) { } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-03-29 18:45:32 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " int f(Item *item) { \n "
" item->x = 0; \n "
" a = b ? c : d; \n "
" if (item) { } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:4]: (warning) Possible null pointer dereference: item - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-03-29 18:45:32 +02:00
2011-01-10 19:57:26 +01:00
check ( " BOOL GotoFlyAnchor() \n " // #2243
" { \n "
" const SwFrm* pFrm = GetCurrFrm(); \n "
" do { \n "
" pFrm = pFrm->GetUpper(); \n "
" } while( pFrm && !pFrm->IsFlyFrm() ); \n "
" \n "
" if( !pFrm ) \n "
" return FALSE; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-01-10 19:57:26 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-01-15 12:09:36 +01:00
// Ticket #2463
2012-12-06 19:19:22 +01:00
check ( " struct A \n "
2011-01-15 12:09:36 +01:00
" { \n "
" B* W; \n "
" \n "
" void f() { \n "
" switch (InData) { \n "
" case 2: \n "
" if (!W) return; \n "
" W->foo(); \n "
" break; \n "
" case 3: \n "
" f(); \n "
" if (!W) return; \n "
" break; \n "
" } \n "
" } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-01-15 12:09:36 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-01-31 17:30:27 +01:00
// #2525 - sizeof
check ( " void f() { \n "
" int *test = NULL; \n "
" int c = sizeof(test[0]); \n "
" if (!test) \n "
" ; \n "
2013-04-15 19:00:15 +02:00
" } " , true , " test.cpp " , false ) ;
2011-01-31 17:30:27 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-08-20 09:47:55 +02:00
2013-11-02 23:56:10 +01:00
check ( " void f(type* p) { \n " // #4983
" x(sizeof p[0]); \n "
" if (!p) \n "
" ; \n "
" } " , false , " test.cpp " , false ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-08-20 09:47:55 +02:00
// #3023 - checked deref
check ( " void f(struct ABC *abc) { \n "
" WARN_ON(!abc || abc->x == 0); \n "
" if (!abc) { } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2011-08-20 09:47:55 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(struct ABC *abc) { \n "
" WARN_ON(!abc || abc->x == 7); \n "
" if (!abc) { } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2011-08-20 09:47:55 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-12-18 13:33:23 +01:00
2014-01-03 18:53:37 +01:00
// #3425 - false positives when there are macros
2011-12-18 13:33:23 +01:00
check ( " void f(int *p) { \n "
" *p = 0; \n "
" $if(!p){} \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-07-23 10:05:55 +02:00
check ( " void f() { \n " // #3914 - false positive
" int *p; \n "
" ((p=ret()) && (x=*p)); \n "
" if (p); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
}
2014-11-20 14:20:09 +01:00
void nullpointer5 ( ) {
2010-10-31 11:51:25 +01:00
// errors..
check ( " void foo(A &a) \n "
" { \n "
" char c = a.c(); \n "
" if (!a) \n "
" return; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
// Execution paths..
2014-11-20 14:20:09 +01:00
void nullpointerExecutionPaths ( ) {
2010-10-31 11:51:25 +01:00
// errors..
check ( " static void foo() \n "
" { \n "
" Foo *p = 0; \n "
2013-04-15 19:00:15 +02:00
" if (a == 1) { \n "
2010-10-31 11:51:25 +01:00
" p = new FooBar; \n "
2013-04-15 19:00:15 +02:00
" } else { if (a == 2) { \n "
" p = new FooCar; } } \n "
2010-10-31 11:51:25 +01:00
" p->abcd(); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-01-30 12:54:19 +01:00
TODO_ASSERT_EQUALS ( " [test.cpp:8]: (error) Possible null pointer dereference: p \n " ,
" " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
2013-04-15 19:00:15 +02:00
check ( " static void foo() { \n "
" int &r = *0; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-15 19:00:15 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
2013-04-15 19:00:15 +02:00
check ( " static void foo(int x) { \n "
" int y = 5 + *0; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-15 19:00:15 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
2011-10-18 19:34:14 +02:00
{
2014-01-22 20:16:31 +01:00
const char code [ ] = " static void foo() { \n "
2011-10-18 19:34:14 +02:00
" Foo<int> *abc = 0; \n "
" abc->a(); \n "
" } \n " ;
// inconclusive=false => no error
check ( code , false ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// inconclusive=true => error
check ( code , true ) ;
2014-01-22 20:16:31 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (error, inconclusive) Possible null pointer dereference: abc \n " , errout . str ( ) ) ;
2011-10-18 19:34:14 +02:00
}
2010-10-31 11:51:25 +01:00
2013-04-15 19:00:15 +02:00
check ( " static void foo() { \n "
" std::cout << *0; "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-15 19:00:15 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
check ( " void f() \n "
" { \n "
" char *c = 0; \n "
" { \n "
" delete c; \n "
" } \n "
" c[0] = 0; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " [test.cpp:7]: (error) Possible null pointer dereference: c \n " , errout . str ( ) ) ;
2013-04-15 19:00:15 +02:00
check ( " static void foo() { \n "
" if (3 > *0); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-15 19:00:15 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
// no false positive..
check ( " static void foo() \n "
" { \n "
" Foo *p = 0; \n "
" p = new Foo; \n "
" p->abcd(); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" int sz = sizeof((*(struct dummy *)0).x); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void get_offset(long &offset) \n "
" { \n "
" mystruct * temp; temp = 0; \n "
" offset = (long)(&(temp->z)); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// Ticket #1893 - try/catch inside else
check ( " 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 "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " 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 "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " [test.cpp:12]: (error) Possible null pointer dereference: Q \n " , errout . str ( ) ) ;
// Ticket #2052 (false positive for 'else continue;')
check ( " 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 ( ) ) ;
// function pointer..
check ( " void foo() \n "
" { \n "
" void (*f)(); \n "
" f = 0; \n "
" f(); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " [test.cpp:5]: (error) Possible null pointer dereference: f \n " , errout . str ( ) ) ;
// loops..
check ( " void f() { \n "
" int *p = 0; \n "
" for (int i = 0; i < 10; ++i) { \n "
" int x = *p + 1; \n "
" } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
check ( " void f(int a) { \n "
" const char *p = 0; \n "
" if (a) { \n "
2011-02-05 12:53:28 +01:00
" p = \" abcd \" ; \n "
2010-10-31 11:51:25 +01:00
" } \n "
" for (int i = 0; i < 3; i++) { \n "
" if (a && (p[i] == '1')); \n "
" } \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-11-29 20:30:23 +01:00
// ticket #2251: taking the address of member
check ( " void f() { \n "
" Fred *fred = 0; \n "
" int x = &fred->x; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2010-11-29 20:30:23 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-18 19:34:14 +02:00
// ticket #3220: calling member function
check ( " void f() { \n "
" Fred *fred = NULL; \n "
" fred->do_something(); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-02-01 20:38:47 +01:00
// ticket #3570 - parsing of conditions
{
check ( " void f() { \n "
" int *p = NULL; \n "
" if (x) \n "
" p = q; \n "
" if (p && *p) { } \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2012-02-01 20:38:47 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" int *p = NULL; \n "
" if (x) \n "
" p = q; \n "
" if (!p || *p) { } \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2012-02-01 20:38:47 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" int *p = NULL; \n "
" if (x) \n "
" p = q; \n "
" if (p || *p) { } \n "
" } " ) ;
2014-06-19 17:29:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:5]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2012-02-01 20:38:47 +01:00
}
2010-10-31 11:51:25 +01:00
}
2010-12-26 13:38:16 +01:00
// Ticket #2350
2014-11-20 14:20:09 +01:00
void nullpointerExecutionPathsLoop ( ) {
2010-12-26 13:38:16 +01:00
// No false positive:
check ( " void foo() { \n "
" int n; \n "
2014-01-22 20:16:31 +01:00
" int *argv32 = p; \n "
2010-12-26 13:38:16 +01:00
" if (x) { \n "
" n = 0; \n "
" argv32 = 0; \n "
" } \n "
" \n "
" for (int i = 0; i < n; i++) { \n "
" argv32[i] = 0; \n "
" } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-12-26 13:38:16 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// No false negative:
check ( " void foo() { \n "
" int n; \n "
" int *argv32; \n "
" if (x) { \n "
" n = 10; \n "
" argv32 = 0; \n "
" } \n "
" \n "
" for (int i = 0; i < n; i++) { \n "
" argv32[i] = 0; \n "
" } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-01-30 12:54:19 +01:00
TODO_ASSERT_EQUALS ( " error " ,
" " , errout . str ( ) ) ;
2011-02-19 20:19:46 +01:00
// #2231 - error if assignment in loop is not used
check ( " void f() { \n "
" char *p = 0; \n "
" \n "
" for (int x = 0; x < 3; ++x) { \n "
" if (y[x] == 0) { \n "
" p = malloc(10); \n "
" break; \n "
" } \n "
" } \n "
" \n "
" *p = 0; \n "
" } " ) ;
2014-09-23 16:06:02 +02:00
ASSERT_EQUALS ( " [test.cpp:11]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
2010-12-26 13:38:16 +01:00
}
2014-11-20 14:20:09 +01:00
void nullpointer7 ( ) {
2010-10-31 11:51:25 +01:00
check ( " void foo() \n "
" { \n "
" wxLongLong x = 0; \n "
" int y = x.GetValue(); \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointer9 ( ) { //#ticket 1778
2010-10-31 11:51:25 +01:00
check ( " void foo() \n "
" { \n "
" std::string * x = 0; \n "
" *x = \" test \" ; \n "
2013-04-15 19:00:15 +02:00
" } " , false , " test.cpp " , false ) ;
2014-01-22 06:38:25 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: x \n "
" [test.cpp:4]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
}
2014-11-20 14:20:09 +01:00
void nullpointer10 ( ) {
2011-05-28 05:30:19 +02:00
check ( " void foo() \n "
" { \n "
" struct my_type* p = 0; \n "
" p->x = 0; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-05-28 05:30:19 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
2011-06-04 04:16:08 +02:00
}
2014-11-20 14:20:09 +01:00
void nullpointer11 ( ) { // ticket #2812
2011-05-28 05:30:19 +02:00
check ( " int foo() \n "
" { \n "
" struct my_type* p; \n "
2012-12-06 19:19:22 +01:00
" p = 0; \n "
2011-05-28 05:30:19 +02:00
" return p->x; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-07-25 21:40:32 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
2011-05-28 05:30:19 +02:00
}
2014-11-20 14:20:09 +01:00
void nullpointer12 ( ) { // ticket #2470, #4035
2012-08-25 12:00:25 +02:00
const char code [ ] = " int foo() \n "
" { \n "
" int* i = nullptr; \n "
" return *i; \n "
" } \n " ;
2013-04-15 19:00:15 +02:00
check ( code , false , " test.cpp " , false ) ; // C++ file => nullptr means NULL
2014-01-22 06:38:25 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: i \n "
" [test.cpp:4]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2011-10-16 12:54:58 +02:00
2013-04-15 19:00:15 +02:00
check ( code , false , " test.c " , false ) ; // C file => nullptr does not mean NULL
2011-10-16 12:54:58 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointer15 ( ) { // #3560
2012-01-28 08:06:03 +01:00
check ( " void f() { \n "
" char *p = 0; \n "
" if (x) p = \" abcd \" ; \n "
" return p ? f(*p) : f(0); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointer16 ( ) { // #3591
2012-02-13 19:46:45 +01:00
check ( " void foo() { \n "
" int *p = 0; \n "
" bar(&p); \n "
" *p = 0; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2012-02-13 19:46:45 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointer17 ( ) { // #3567
2012-03-07 20:31:23 +01:00
check ( " int foo() { \n "
" int *p = 0; \n "
2013-04-15 19:00:15 +02:00
" if (x) { return 0; } \n "
" return !p || *p; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2012-03-07 20:31:23 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " int foo() { \n "
" int *p = 0; \n "
2013-04-15 19:00:15 +02:00
" if (x) { return 0; } \n "
2012-03-07 20:31:23 +01:00
" return p && *p; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2012-03-07 20:31:23 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointer18 ( ) { // #1927
2012-04-01 15:54:41 +02:00
check ( " void f () \n "
" { \n "
" int i=0; \n "
2012-04-01 15:56:48 +02:00
" char *str=NULL; \n "
" while (str[i]) \n "
" { \n "
" i++; \n "
" }; \n "
2013-04-15 19:00:15 +02:00
" } \n " , false , " test.cpp " , false ) ;
2014-01-22 06:38:25 +01:00
ASSERT_EQUALS ( " [test.cpp:5]: (error) Possible null pointer dereference: str \n "
" [test.cpp:5]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2012-04-01 15:54:41 +02:00
}
2014-11-20 14:20:09 +01:00
void nullpointer19 ( ) { // #3811
2012-05-16 09:56:39 +02:00
check ( " int foo() { \n "
" perror(0); \n "
" } " , true ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointer20 ( ) { // #3807
2012-05-31 18:41:00 +02:00
check ( " void f(int x) { \n "
" struct xy *p = 0; \n "
" if (x) p = q; \n "
" if (p ? p->x || p->y : 0) { } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int x) { \n " // false negative
" struct xy *p = 0; \n "
" if (x) p = q; \n "
" if (y ? p->x : p->y) { } \n "
" } " ) ;
2014-01-22 20:16:31 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
2012-05-31 18:41:00 +02:00
}
2014-11-20 14:20:09 +01:00
void nullpointer21 ( ) { // #4038 - fp: if (x) p=q; else return;
2012-09-23 09:20:16 +02:00
check ( " void f(int x) { \n "
" int *p = 0; \n "
" if (x) p = q; \n "
" else return; \n "
" *p = 0; \n " // <- p is not NULL
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointer23 ( ) { // #4665
2013-03-19 08:47:05 +01:00
check ( " void f(){ \n "
" char *c = NULL; \n "
" char cBuf[10]; \n "
" sprintf(cBuf, \" %s \" , c ? c : \" 0 \" ); \n "
" } " ) ;
2013-11-04 23:09:15 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-03-19 08:47:05 +01:00
}
2014-11-20 14:20:09 +01:00
void nullpointer24 ( ) { // #5083 - fp: chained assignment
2013-10-20 13:37:36 +02:00
check ( " void f(){ \n "
" char *c = NULL; \n "
" x = c = new char[10]; \n "
" *c = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointer25 ( ) { // #5061
2014-03-26 12:17:27 +01:00
check ( " void f(int *data, int i) \n "
" { \n "
" int *array = NULL; \n "
" if (data == 1 && array[i] == 0) \n "
" std::cout << \" test \" ; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: array \n " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointer26 ( ) { // #3589
2014-03-27 19:16:30 +01:00
check ( " double foo() { \n "
" sk *t1 = foo(); \n "
" sk *t2 = foo(); \n "
" if ((!t1) && (!t2)) \n "
" return 0.0; \n "
" if (t1 && (!t2)) \n "
" return t1->Inter(); \n "
" if (t2->GetT() == t) \n "
" return t2->Inter(); \n "
" if (t2 && (!t1)) \n "
" return 0.0; \n "
" return 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2015-01-05 14:54:24 +01:00
void nullpointer_addressOf ( ) { // address of
check ( " void f() { \n "
" struct X *x = 0; \n "
" if (addr == &x->y) {} \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" struct X *x = 0; \n "
" if (addr == &x->y.z[0]) {} \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointerSwitch ( ) { // #2626
2014-03-28 10:06:24 +01:00
check ( " char *f(int x) { \n "
" char *p = do_something(); \n "
" switch (x) { \n "
" case 1: \n "
" p = 0; \n "
" case 2: \n "
" *p = 0; \n "
" break; \n "
" } \n "
" return p; \n "
" } " , true , " test.cpp " , false ) ;
ASSERT_EQUALS ( " [test.cpp:7]: (error) Possible null pointer dereference: p \n "
" [test.cpp:7]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointer_cast ( ) { // #4692
2013-04-03 10:27:08 +02:00
check ( " char *nasm_skip_spaces(const char *p) { \n "
" if (p) \n "
" while (*p && nasm_isspace(*p)) \n "
" p++; \n "
2013-04-15 19:00:15 +02:00
" return p; \n "
2013-04-03 10:27:08 +02:00
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void nullpointer_castToVoid ( ) { // #3771
2012-04-30 12:36:41 +02:00
check ( " void f () { \n "
2013-04-15 19:00:15 +02:00
" int *buf; buf = NULL; \n "
" buf; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-10-31 11:51:25 +01:00
// Check if pointer is null and the dereference it
2014-11-20 14:20:09 +01:00
void pointerCheckAndDeRef ( ) {
2010-10-31 11:51:25 +01:00
check ( " void foo(char *p) { \n "
" if (!p) { \n "
" } \n "
" *p = 0; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
2010-11-04 21:22:29 +01:00
check ( " void foo(char *p) { \n "
" if (NULL == p) { \n "
" } \n "
" *p = 0; \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2010-11-04 21:22:29 +01:00
check ( " void foo(char *p) { \n "
" if (p == NULL) { \n "
" } \n "
" *p = 0; \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2010-11-04 21:22:29 +01:00
2010-11-12 19:42:02 +01:00
check ( " void foo(char *p) { \n "
" if (p == NULL) { \n "
" } \n "
" printf( \" %c \" , *p); \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2010-11-12 19:42:02 +01:00
2011-02-19 21:28:18 +01:00
check ( " void foo(char *p) { \n "
" if (p && *p == 0) { \n "
" } \n "
" printf( \" %c \" , *p); \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-02-19 21:28:18 +01:00
2011-02-20 14:38:49 +01:00
check ( " void foo(char *p) { \n "
" if (p && *p == 0) { \n "
" } else { *p = 0; } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-02-20 14:38:49 +01:00
2011-07-31 17:19:23 +02:00
check ( " void foo(char *p) { \n "
" if (p) { \n "
" } \n "
" strcpy(p, \" abc \" ); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-07-31 17:19:23 +02:00
2011-07-31 17:32:25 +02:00
check ( " void foo(char *p) { \n "
" if (p) { \n "
" } \n "
" bar(); \n "
" strcpy(p, \" abc \" ); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-07-31 17:32:25 +02:00
2010-10-31 11:51:25 +01:00
check ( " void foo(abc *p) { \n "
" if (!p) { \n "
" } \n "
2013-04-15 19:00:15 +02:00
" else { if (!p->x) { \n "
" } } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-04-13 10:49:17 +02:00
{
static const char code [ ] =
" void foo(char *p) { \n "
" if (!p) { \n "
" abort(); \n "
" } \n "
" *p = 0; \n "
" } " ;
check ( code , false ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
2013-04-13 10:49:17 +02:00
check ( code , true ) ;
2014-03-21 17:36:48 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-04-13 10:49:17 +02:00
}
2011-10-29 10:35:31 +02:00
check ( " void foo(char *p) { \n "
" if (!p) { \n "
2011-01-05 21:48:26 +01:00
" (*bail)(); \n "
" } \n "
" *p = 0; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-01-05 21:48:26 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
check ( " void foo(char *p) { \n "
" if (!p) { \n "
" throw x; \n "
" } \n "
" *p = 0; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-09-03 19:43:27 +02:00
check ( " void foo(char *p) { \n "
" if (!p) { \n "
" ab.abort(); \n "
" } \n "
" *p = 0; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-09-03 19:43:27 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-11-04 21:09:32 +01:00
check ( " void foo(char *p) { \n "
2010-10-31 11:51:25 +01:00
" if (!p) { \n "
" switch (x) { } \n "
" } \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-11-04 21:09:32 +01:00
check ( " void foo(char *p) { \n "
2010-11-01 19:21:08 +01:00
" if (!p) { \n "
" } \n "
" return *x; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2010-11-01 19:21:08 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-01-25 15:16:22 +01:00
check ( " int foo(int *p) { \n "
" if (!p) { \n "
" x = *p; \n "
" return 5+*p; \n "
" } \n "
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n "
" [test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2012-01-25 15:16:22 +01:00
2010-11-04 21:09:32 +01:00
// operator!
check ( " void f() { \n "
" A a; \n "
" if (!a) { \n "
" a.x(); \n "
" } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-11-04 21:09:32 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
// This is why this check can't be used on the simplified token list
check ( " void f(Foo *foo) { \n "
" if (!dynamic_cast<bar *>(foo)) { \n "
" *foo = 0; \n "
" } \n "
2013-04-15 19:00:15 +02:00
" } " , false , " test.cpp " , false ) ;
2010-10-31 11:51:25 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-16 21:41:50 +01:00
// ticket: #2300 - calling unknown function that may initialize the pointer
check ( " Fred *fred; \n "
" void a() { \n "
" if (!fred) { \n "
" initfred(); \n "
" fred->x = 0; \n "
" } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-12-16 21:41:50 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-01-09 20:16:16 +01:00
// ticket #1219
check ( " void foo(char *p) { \n "
" if (p) { \n "
" return; \n "
" } \n "
" *p = 0; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-01-17 19:23:00 +01:00
// #2467 - unknown macro may terminate the application
check ( " void f(Fred *fred) { \n "
" if (fred == NULL) { \n "
" MACRO; \n "
" } \n "
" fred->a(); \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2011-01-17 19:23:00 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-01-23 08:38:09 +01:00
// #2493 - switch
check ( " void f(Fred *fred) { \n "
" if (fred == NULL) { \n "
" x = 0; \n "
" } \n "
" switch (x) { \n "
" case 1: \n "
" fred->a(); \n "
" break; \n "
" }; \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2011-01-23 08:38:09 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-02-18 20:05:44 +01:00
2012-09-18 19:16:28 +02:00
// #4118 - second if
check ( " void f(char *p) { \n "
" int x = 1; \n "
" if (!p) x = 0; \n "
" if (x) *p = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-02-18 20:05:44 +01:00
// #2582 - segmentation fault
check ( " if() " ) ;
2011-03-27 11:04:58 +02:00
// #2674 - different functions
check ( " class Fred { \n "
" public: \n "
" Wilma *wilma; \n "
" void a(); \n "
" void b(); \n "
" }; \n "
" \n "
" void Fred::a() { \n "
" if ( wilma ) { } \n "
" } \n "
" \n "
" void Fred::b() { \n "
" wilma->Reload(); \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2011-03-27 11:04:58 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-03-27 21:29:49 +02:00
check ( " void test(int *i) { \n "
2013-04-15 19:00:15 +02:00
" if(i == NULL) { } \n "
" else { \n "
2011-03-27 21:29:49 +02:00
" int b = *i; \n "
" } \n "
2015-01-31 20:12:02 +01:00
" } " , true , " test.cpp " , false ) ;
2011-03-27 21:29:49 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-04-03 21:06:42 +02:00
// #2696 - false positives nr 1
check ( " void f() \n "
" { \n "
" struct foo *pFoo = NULL; \n "
" size_t len; \n "
" \n "
" len = sizeof(*pFoo) - sizeof(pFoo->data); \n "
" \n "
" if (pFoo) \n "
" bar(); \n "
2013-04-15 19:00:15 +02:00
" } " , true , " test.cpp " , false ) ;
2011-04-03 21:06:42 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// #2696 - false positives nr 2
check ( " void f() \n "
" { \n "
" struct foo *pFoo = NULL; \n "
" size_t len; \n "
" \n "
" while (pFoo) \n "
" pFoo = pFoo->next; \n "
" \n "
" len = sizeof(pFoo->data); \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2011-04-03 21:06:42 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// #2696 - false positives nr 3
check ( " void f() \n "
" { \n "
" struct foo *pFoo = NULL; \n "
" size_t len; \n "
" \n "
" while (pFoo) \n "
" pFoo = pFoo->next; \n "
" \n "
" len = decltype(*pFoo); \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2011-04-03 21:06:42 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-07-25 21:58:00 +02:00
check ( " int foo(struct Fred *fred) { \n "
2013-04-15 19:00:15 +02:00
" if (fred) { } \n "
2011-07-25 21:58:00 +02:00
" return fred->a; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: fred - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-08-01 07:51:32 +02:00
// #2789 - assign and check pointer
check ( " void f() { \n "
2013-04-15 19:00:15 +02:00
" char *p; p = x(); \n "
" if (!p) { } \n "
2011-08-01 07:51:32 +02:00
" *p = 0; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:3]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-08-07 17:06:25 +02:00
// check, assign and use
check ( " void f() { \n "
" char *p; \n "
" if (p == 0 && (p = malloc(10)) != 0) { \n "
" *p = 0; \n "
" } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2011-08-07 17:06:25 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-29 15:48:54 +02:00
2012-02-11 16:15:38 +01:00
// check, assign and use
check ( " void f() { \n "
" char *p; \n "
" if (p == 0 && (p = malloc(10)) != a && (*p = a)) { \n "
" *p = 0; \n "
" } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2012-02-11 16:15:38 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// check, and use
check ( " void f() { \n "
" char *p; \n "
" if (p == 0 && (*p = 0)) { \n "
" return; \n "
" } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:3]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2012-02-11 16:15:38 +01:00
// check, and use
check ( " void f() { \n "
" struct foo *p; \n "
" if (p == 0 && p->x == 10) { \n "
" return; \n "
" } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:3]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2012-02-11 16:15:38 +01:00
// check, and use
check ( " void f() { \n "
" struct foo *p; \n "
" if (p == 0 || p->x == 10) { \n "
" return; \n "
" } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2012-02-11 16:15:38 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// check, and use
check ( " void f() { \n "
2013-04-15 19:00:15 +02:00
" char *p; p = malloc(10); \n "
" if (p == NULL && (*p = a)) { \n "
2012-02-11 16:15:38 +01:00
" return; \n "
" } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:3]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2012-02-11 16:15:38 +01:00
// check, and use
check ( " void f(struct X *p, int x) { \n "
" if (!p && x==1 || p && p->x==0) { \n "
" return; \n "
" } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2012-02-11 16:15:38 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-29 15:48:54 +02:00
{
const char code [ ] = " void f(Fred *fred) { \n "
" if (fred == NULL) { } \n "
" fred->x(); \n "
" } " ;
2015-01-31 20:12:02 +01:00
check ( code , false , " test.cpp " , false ) ; // non-inconclusive
2011-10-29 15:48:54 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2015-01-31 20:12:02 +01:00
check ( code , true , " test.cpp " , false ) ; // inconclusive
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:2]: (warning, inconclusive) Possible null pointer dereference: fred - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-10-29 15:48:54 +02:00
}
2011-12-03 13:10:07 +01:00
check ( " void f(char *s) { \n " // #3358
" if (s==0); \n "
" strcpy(a, s?b:c); \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2011-12-03 13:10:07 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-12-17 12:44:11 +01:00
// sizeof
check ( " void f(struct fred_t *fred) { \n "
" if (!fred) \n "
2013-04-15 19:00:15 +02:00
" int sz = sizeof(fred->x); \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2011-12-17 12:44:11 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-12-18 13:33:23 +01:00
// check in macro
check ( " void f(int *x) { \n "
" $if (!x) {} \n "
" *x = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-12-25 14:23:50 +01:00
// return ?:
check ( " int f(ABC *p) { \n " // FP : return ?:
" if (!p) {} \n "
" return p ? p->x : 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " int f(ABC *p) { \n " // no fn
" if (!p) {} \n "
" return q ? p->x : 0; \n "
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2014-04-02 19:39:42 +02:00
check ( " int f(ABC *p) { \n " // FP : return &&
" if (!p) {} \n "
" return p && p->x; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2014-09-02 12:03:05 +02:00
check ( " void f(int x, int *p) { \n "
" if (x || !p) {} \n "
" *p = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
}
2010-12-26 19:29:58 +01:00
// Test CheckNullPointer::nullConstantDereference
2014-11-20 14:20:09 +01:00
void nullConstantDereference ( ) {
2012-01-25 15:16:22 +01:00
check ( " void f() { \n "
" int* p = 0; \n "
" return p[4]; \n "
2013-04-15 19:00:15 +02:00
" } " , false , " test.cpp " , false ) ;
2014-01-22 06:38:25 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: p \n "
" [test.cpp:3]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2013-06-07 06:37:53 +02:00
2013-10-12 15:19:15 +02:00
check ( " void f() { \n "
" typeof(*NULL) y; \n "
" } " , true ) ;
2013-11-08 13:22:07 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-12-26 19:29:58 +01:00
}
2014-11-20 14:20:09 +01:00
void gcc_statement_expression ( ) {
2011-03-13 10:34:54 +01:00
// Ticket #2621
check ( " void f(struct ABC *abc) { \n "
" ({ if (abc) dbg(); }) \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-06-26 21:46:33 +02:00
2014-11-20 14:20:09 +01:00
void snprintf_with_zero_size ( ) {
2011-06-26 21:46:33 +02:00
// Ticket #2840
check ( " void f() { \n "
" int bytes = snprintf(0, 0, \" %u \" , 1); \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2011-06-26 21:46:33 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void snprintf_with_non_zero_size ( ) {
2011-06-26 21:46:33 +02:00
// Ticket #2840
check ( " void f() { \n "
" int bytes = snprintf(0, 10, \" %u \" , 1); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
}
2011-10-12 22:11:27 +02:00
2014-11-20 14:20:09 +01:00
void printf_with_invalid_va_argument ( ) {
2011-10-12 22:11:27 +02:00
check ( " void f() { \n "
" printf( \" %s \" , 0); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
check ( " void f(char* s) { \n "
" printf( \" %s \" , s); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" char* s = 0; \n "
" printf( \" %s \" , s); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: s \n " , errout . str ( ) ) ;
2011-12-03 13:10:07 +01:00
check ( " void f() { \n "
" char *s = 0; \n "
" printf( \" %s \" , s == 0 ? a : s); \n "
2013-04-15 19:00:15 +02:00
" } " , false , " test.cpp " , false ) ;
2011-12-03 13:10:07 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-12 22:11:27 +02:00
check ( " void f() { \n "
" printf( \" %u%s \" , 0, 0); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
check ( " void f(char* s) { \n "
" printf( \" %u%s \" , 0, s); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" char* s = 0; \n "
" printf( \" %u%s \" , 123, s); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: s \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" printf( \" %%%s%% \" , 0); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
check ( " void f(char* s) { \n "
" printf( \" text: %s, %s \" , s, 0); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" char* s = \" blabla \" ; \n "
" printf( \" %s \" , s); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-11-28 21:32:07 +01:00
check ( " void f(char* s) { \n "
" printf( \" text: %m%s, %s \" , s, 0); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
check ( " void f(char* s) { \n "
" printf( \" text: %*s, %s \" , s, 0); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2011-11-30 20:23:29 +01:00
// Ticket #3364
check ( " void f() { \n "
" printf( \" %-*.*s \" , s, 0); \n "
" sprintf( \" %* \" , s); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-12 22:11:27 +02:00
}
2014-11-20 14:20:09 +01:00
void scanf_with_invalid_va_argument ( ) {
2011-10-12 22:11:27 +02:00
check ( " void f(char* s) { \n "
" sscanf(s, \" %s \" , 0); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" scanf( \" %d \" , 0); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2011-10-16 07:06:18 +02:00
check ( " void f(char* foo) { \n "
" char location[200]; \n "
" int width, height; \n "
" sscanf(imgInfo, \" %s %d %d \" , location, &width, &height); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ; // ticket #3207
check ( " void f(char *dummy) { \n "
" int iVal; \n "
" sscanf(dummy, \" %d%c \" , &iVal); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ; // ticket #3211
check ( " void f(char *dummy) { \n "
" int* iVal = 0; \n "
" sscanf(dummy, \" %d \" , iVal); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: iVal \n " , errout . str ( ) ) ;
check ( " void f(char *dummy) { \n "
" int* iVal; \n "
" sscanf(dummy, \" %d \" , foo(iVal)); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(char *dummy) { \n "
" int* iVal = 0; \n "
" sscanf(dummy, \" %d%d \" , foo(iVal), iVal); \n "
" } " ) ;
2014-01-22 20:16:31 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-12-02 17:09:32 +01:00
check ( " void f(char* dummy) { \n "
" sscanf(dummy, \" %*d%u \" , 0); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2011-10-12 22:11:27 +02:00
}
2011-10-23 23:36:57 +02:00
2014-11-20 14:20:09 +01:00
void nullpointer_in_return ( ) {
2011-10-23 23:36:57 +02:00
check ( " int foo() { \n "
" int* iVal = 0; \n "
" if(g()) iVal = g(); \n "
" return iVal[0]; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: iVal \n " , errout . str ( ) ) ;
check ( " int foo(int* iVal) { \n "
" return iVal[0]; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2011-10-23 23:36:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-11-04 09:49:49 +01:00
2014-11-20 14:20:09 +01:00
void nullpointer_in_typeid ( ) {
2011-11-04 09:49:49 +01:00
// Should throw std::bad_typeid
check ( " struct PolymorphicA { virtual ~A() {} }; \n "
" bool foo() { \n "
" PolymorphicA* a = 0; \n "
" return typeid(*a) == typeid(*a); \n "
2013-04-15 19:00:15 +02:00
" } " , true , " test.cpp " , false ) ;
2011-11-11 09:58:17 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-11-04 09:49:49 +01:00
check ( " struct NonPolymorphicA { ~A() {} }; \n "
" bool foo() { \n "
" NonPolymorphicA* a = 0; \n "
" return typeid(*a) == typeid(*a); \n "
2013-04-15 19:00:15 +02:00
" } " , true , " test.cpp " , false ) ;
2011-11-11 09:58:17 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-11-04 09:49:49 +01:00
check ( " bool foo() { \n "
" char* c = 0; \n "
" return typeid(*c) == typeid(*c); \n "
2013-04-15 19:00:15 +02:00
" } " , true , " test.cpp " , false ) ;
2011-11-11 09:58:17 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-11-04 09:49:49 +01:00
}
2014-11-20 14:20:09 +01:00
void nullpointer_in_for_loop ( ) {
2011-11-07 21:10:21 +01:00
// Ticket #3278
check ( " void f(int* ptr, int cnt){ \n "
" if (!ptr) \n "
" cnt = 0; \n "
" for (int i = 0; i < cnt; ++i) \n "
" *ptr++ = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-11-13 22:35:13 +01:00
2014-11-20 14:20:09 +01:00
void nullpointerDelete ( ) {
2011-11-13 22:35:13 +01:00
check ( " void f() { \n "
" K *k = getK(); \n "
" if (k) \n "
" k->doStuff(); \n "
" delete k; \n "
" } \n " , true ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" K *k = getK(); \n "
" if (k) \n "
" k[0] = ptr; \n "
" delete [] k; \n "
" k = new K[10]; \n "
" } \n " , true ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-11-23 21:19:54 +01:00
2014-11-20 14:20:09 +01:00
void nullpointerExit ( ) {
2011-11-23 21:19:54 +01:00
check ( " void f() { \n "
" K *k = getK(); \n "
" if (!k) \n "
" exit(1); \n "
" k->f(); \n "
" } \n " , true ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-12-25 17:01:45 +01:00
2014-11-20 14:20:09 +01:00
void nullpointerStdString ( ) {
2012-01-25 15:16:22 +01:00
check ( " void f(std::string s1) { \n "
" void* p = 0; \n "
" s1 = 0; \n "
2014-09-26 20:40:44 +02:00
" s1 = ' \\ 0'; \n "
2012-01-25 15:16:22 +01:00
" std::string s2 = 0; \n "
2014-09-26 20:40:44 +02:00
" std::string s2 = ' \\ 0'; \n "
2012-01-25 15:16:22 +01:00
" std::string s3(0); \n "
" foo(std::string(0)); \n "
" s1 = p; \n "
" std::string s4 = p; \n "
" std::string s5(p); \n "
" foo(std::string(p)); \n "
" } " , true ) ;
2014-09-26 20:40:44 +02:00
ASSERT_EQUALS ( " [test.cpp:9]: (error) Possible null pointer dereference: p \n "
2014-01-22 20:16:31 +01:00
" [test.cpp:10]: (error) Possible null pointer dereference: p \n "
2014-10-16 19:12:02 +02:00
" [test.cpp:3]: (error) Null pointer dereference \n "
" [test.cpp:5]: (error) Null pointer dereference \n "
2014-09-26 20:40:44 +02:00
" [test.cpp:7]: (error) Null pointer dereference \n "
" [test.cpp:8]: (error) Null pointer dereference \n "
2014-10-18 11:18:07 +02:00
/*"[test.cpp:11]: (error) Possible null pointer dereference: p\n"
" [test.cpp:12]: (error) Possible null pointer dereference: p \n " */
2014-01-22 20:16:31 +01:00
, errout . str ( ) ) ;
2012-01-25 15:16:22 +01:00
check ( " void f(std::string s1, const std::string& s2, const std::string* s3) { \n "
" void* p = 0; \n "
2013-04-15 19:00:15 +02:00
" if (x) { return; } \n "
2012-01-25 15:16:22 +01:00
" foo(s1 == p); \n "
" foo(s2 == p); \n "
" foo(s3 == p); \n "
" foo(p == s1); \n "
" foo(p == s2); \n "
" foo(p == s3); \n "
" } " , true ) ;
2013-04-15 19:00:15 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: p \n "
" [test.cpp:5]: (error) Possible null pointer dereference: p \n "
" [test.cpp:7]: (error) Possible null pointer dereference: p \n "
" [test.cpp:8]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
2012-01-26 16:50:59 +01:00
check ( " class Bar { \n "
" std::string s; \n "
" Bar() : s(0) {} \n "
" }; \n "
" class Foo { \n "
" std::string s; \n "
" Foo(); \n "
" }; \n "
" Foo::Foo() : s(0) {} " ) ;
2012-04-23 18:26:27 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Null pointer dereference \n "
" [test.cpp:9]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2012-04-02 12:12:02 +02:00
check ( " void f() { \n "
" std::string s = 0 == x ? \" a \" : \" b \" ; \n "
" } " , true ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-08-24 21:50:19 +02:00
check ( " void f() { \n "
" const std::string s = g(); \n "
" ASSERT_MESSAGE( \" Error on s \" , 0 == s.compare( \" Some text \" )); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-01-25 15:16:22 +01:00
}
2014-11-20 14:20:09 +01:00
void nullpointerStdStream ( ) {
2012-03-16 17:24:03 +01:00
check ( " void f(std::ifstream& is) { \n "
" char* p = 0; \n "
" is >> p; \n "
" } " ) ;
2014-05-17 16:44:44 +02:00
TODO_ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: p \n " , " " , errout . str ( ) ) ;
2012-03-16 17:24:03 +01:00
check ( " void f(const std::ostringstream& oss, char* q) { \n "
" char const* p = 0; \n " // Simplification makes detection of bug difficult
" oss << p; \n "
" oss << foo << p; \n "
" if(q == 0) \n "
" oss << foo << q; \n "
2013-04-15 19:00:15 +02:00
" } " , false , " test.cpp " , false ) ;
2014-05-17 16:44:44 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: p \n "
" [test.cpp:4]: (error) Possible null pointer dereference: p \n "
" [test.cpp:6] -> [test.cpp:5]: (warning) Possible null pointer dereference: q - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2012-03-16 17:24:03 +01:00
check ( " void f(const char* p) { \n "
" if(p == 0) { \n "
" std::cout << p; \n "
" std::cerr << p; \n "
" std::cin >> p; \n "
" std::cout << abc << p; \n "
" } \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2014-06-22 10:02:14 +02:00
TODO_ASSERT_EQUALS ( " [test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n "
" [test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n "
" [test.cpp:5] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n "
2014-06-23 11:59:14 +02:00
" [test.cpp:6] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " ,
2014-06-22 10:02:14 +02:00
" [test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n "
" [test.cpp:4] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " ,
errout . str ( ) ) ;
2012-03-16 17:24:03 +01:00
check ( " void f() { \n "
" void* p1 = 0; \n "
" std::cout << p1; \n " // No char*
" char* p2 = 0; \n "
" std::cin >> (int)p; \n " // result casted
" std::cout << (int)p; \n "
2013-04-15 19:00:15 +02:00
" } " , true , " test.cpp " , false ) ;
2012-03-16 17:24:03 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(const std::string& str) { \n "
" long long ret = 0; \n "
" std::istringstream istr(str); \n "
" istr >> std::hex >> ret; \n " // Read integer
" return ret; \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2012-03-16 17:24:03 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-11-10 19:53:20 +01:00
check ( " void f(int* i) { \n "
" if(i) return; \n "
" std::cout << i; \n " // Its no char* (#4240)
" } " , true ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2014-05-17 18:18:20 +02:00
// #5811 false postive: (error) Null pointer dereference
check ( " using namespace std; \n "
" std::string itoip(int ip) { \n "
" stringstream out; \n "
" out << ((ip >> 0) & 0xFF); \n "
" return out.str(); \n "
" }n " , true , " test.cpp " , false ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2014-05-17 19:14:29 +02:00
// avoid regression from first fix attempt for #5811...
check ( " void deserialize(const std::string &data) { \n "
" std::istringstream iss(data); \n "
" unsigned int len = 0; \n "
" if (!(iss >> len)) \n "
" return; \n "
" } \n " , true , " test.cpp " , false ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-03-16 17:24:03 +01:00
}
2014-11-20 14:20:09 +01:00
void functioncall ( ) { // #3443 - function calls
2011-12-25 17:01:45 +01:00
// dereference pointer and then check if it's null
{
// function not seen
check ( " void f(int *p) { \n "
" *p = 0; \n "
" foo(p); \n "
" if (p) { } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// function seen (taking pointer parameter)
check ( " void foo(int *p) { } \n "
" \n "
" void f(int *p) { \n "
" *p = 0; \n "
" foo(p); \n "
" if (p) { } \n "
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:6]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-12-25 17:01:45 +01:00
2012-09-06 18:33:15 +02:00
// function seen (taking reference parameter)
check ( " void foo(int *&p) { } \n "
" \n "
" void f(int *p) { \n "
" *p = 0; \n "
" foo(p); \n "
" if (p) { } \n "
" } " , true ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-12-25 17:01:45 +01:00
// function implementation not seen
check ( " void foo(int *p); \n "
" \n "
" void f(int *p) { \n "
" *p = 0; \n "
" foo(p); \n "
" if (p) { } \n "
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:6]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-12-26 07:13:10 +01:00
// inconclusive
check ( " void f(int *p) { \n "
" *p = 0; \n "
" foo(p); \n "
" if (p) { } \n "
" } " , true ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:4]: (warning, inconclusive) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-12-25 17:01:45 +01:00
}
// dereference struct pointer and then check if it's null
{
// function not seen
check ( " void f(struct ABC *abc) { \n "
" abc->a = 0; \n "
" foo(abc); \n "
" if (abc) { } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// function seen (taking pointer parameter)
check ( " void foo(struct ABC *abc) { } \n "
" \n "
" void f(struct ABC *abc) { \n "
" abc->a = 0; \n "
" foo(abc); \n "
" if (abc) { } \n "
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:6]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-12-25 17:01:45 +01:00
// function implementation not seen
check ( " void foo(struct ABC *abc); \n "
" \n "
" void f(struct ABC *abc) { \n "
" abc->a = 0; \n "
" foo(abc); \n "
" if (abc) { } \n "
" } " ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:4] -> [test.cpp:6]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-12-26 07:13:10 +01:00
// inconclusive
check ( " void f(struct ABC *abc) { \n "
" abc->a = 0; \n "
" foo(abc); \n "
" if (abc) { } \n "
" } " , true ) ;
2013-04-07 03:41:02 +02:00
ASSERT_EQUALS ( " [test.cpp:2] -> [test.cpp:4]: (warning, inconclusive) Possible null pointer dereference: abc - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
2011-12-25 17:01:45 +01:00
}
}
2012-01-31 15:49:34 +01:00
2014-11-20 14:20:09 +01:00
void functioncalllibrary ( ) {
2014-04-02 19:39:42 +02:00
Settings settings1 ;
Tokenizer tokenizer ( & settings1 , this ) ;
2013-07-15 21:57:58 +02:00
std : : istringstream code ( " void f() { int a,b; x(a,b); } " ) ;
tokenizer . tokenize ( code , " test.c " ) ;
const Token * xtok = Token : : findsimplematch ( tokenizer . tokens ( ) , " x " ) ;
// nothing bad..
{
Library library ;
2013-07-22 20:21:45 +02:00
Library : : ArgumentChecks arg ;
2013-07-16 09:40:31 +02:00
library . argumentChecks [ " x " ] [ 1 ] = arg ;
library . argumentChecks [ " x " ] [ 2 ] = arg ;
2013-07-15 21:57:58 +02:00
std : : list < const Token * > null , uninit ;
CheckNullPointer : : parseFunctionCall ( * xtok , null , & library , 0U ) ;
CheckNullPointer : : parseFunctionCall ( * xtok , uninit , & library , 1U ) ;
ASSERT_EQUALS ( 0U , null . size ( ) ) ;
ASSERT_EQUALS ( 0U , uninit . size ( ) ) ;
}
// for 1st parameter null pointer is not ok..
{
Library library ;
2013-12-26 17:48:25 +01:00
Library : : ArgumentChecks arg ;
2013-07-16 09:40:31 +02:00
library . argumentChecks [ " x " ] [ 1 ] = arg ;
library . argumentChecks [ " x " ] [ 2 ] = arg ;
library . argumentChecks [ " x " ] [ 1 ] . notnull = true ;
2013-07-15 21:57:58 +02:00
std : : list < const Token * > null , uninit ;
CheckNullPointer : : parseFunctionCall ( * xtok , null , & library , 0U ) ;
CheckNullPointer : : parseFunctionCall ( * xtok , uninit , & library , 1U ) ;
ASSERT_EQUALS ( 1U , null . size ( ) ) ;
ASSERT_EQUALS ( " a " , null . front ( ) - > str ( ) ) ;
ASSERT_EQUALS ( 0U , uninit . size ( ) ) ;
}
// for 2nd parameter uninit data is not ok..
{
Library library ;
2013-07-22 20:21:45 +02:00
Library : : ArgumentChecks arg ;
2013-07-16 09:40:31 +02:00
library . argumentChecks [ " x " ] [ 1 ] = arg ;
library . argumentChecks [ " x " ] [ 2 ] = arg ;
library . argumentChecks [ " x " ] [ 2 ] . notuninit = true ;
2013-07-15 21:57:58 +02:00
std : : list < const Token * > null , uninit ;
CheckNullPointer : : parseFunctionCall ( * xtok , null , & library , 0U ) ;
CheckNullPointer : : parseFunctionCall ( * xtok , uninit , & library , 1U ) ;
ASSERT_EQUALS ( 0U , null . size ( ) ) ;
ASSERT_EQUALS ( 1U , uninit . size ( ) ) ;
ASSERT_EQUALS ( " b " , uninit . front ( ) - > str ( ) ) ;
}
}
2012-11-21 08:56:17 +01:00
2014-11-20 14:20:09 +01:00
void functioncallDefaultArguments ( ) {
2012-11-21 08:56:17 +01:00
check ( " void f(int *p = 0) { \n "
" *p = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Possible null pointer dereference if the default parameter value is used: p \n " , errout . str ( ) ) ;
2013-04-25 09:25:56 +02:00
check ( " void f(int *p = 0) { \n "
" if (!p) \n "
" return; \n "
" *p = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-11-21 08:56:17 +01:00
check ( " void f(char a, int *p = 0) { \n "
" *p = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Possible null pointer dereference if the default parameter value is used: p \n " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" printf( \" p = %d \" , *p); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Possible null pointer dereference if the default parameter value is used: p \n " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" printf( \" p[1] = %d \" , p[1]); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Possible null pointer dereference if the default parameter value is used: p \n " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" if (p != 0 && bar()) \n "
" *p = 0; \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2012-11-21 08:56:17 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p) { \n "
" *p = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" if (p != 0) \n "
" *p = 0; \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2012-11-21 08:56:17 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-01-10 08:22:54 +01:00
check ( " void f(int *p = 0) { \n "
" int y; \n "
" if (p == 0) \n "
" p = &y; \n "
" *p = 0; \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-01-10 08:22:54 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-11-21 08:56:17 +01:00
check ( " void f(int *p = 0) { \n "
" if (a != 0) \n "
" *p = 0; \n "
2015-02-01 15:05:00 +01:00
" } " , true , " test.cpp " , false ) ;
TODO_ASSERT_EQUALS ( " [test.cpp:3]: (warning) Possible null pointer dereference if the default parameter value is used: p \n " , " " , errout . str ( ) ) ;
2012-11-21 08:56:17 +01:00
check ( " void f(int *p = 0) { \n "
" p = a; \n "
2013-04-15 19:00:15 +02:00
" *p = 0; \n " // <- don't simplify and verify
" } " , false , " test.cpp " , false ) ;
2012-11-21 08:56:17 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" p += a; \n "
" *p = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-02-28 08:45:21 +01:00
check ( " int f(int *p = 0) { \n "
" if (p == 0) { \n "
" return 0; \n "
" } \n "
" return *p; \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-02-28 08:45:21 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
2014-05-22 19:48:00 +02:00
" std::cout << p ? *p : 0; \n " // Due to operator precedence, this is equivalent to: (std::cout << p) ? *p : 0;
" } " ) ;
TODO_ASSERT_EQUALS ( " [test.cpp:2]: (warning) Possible null pointer dereference if the default parameter value is used: p \n " , " " , errout . str ( ) ) ; // Check the first branch of ternary
check ( " void f(char *p = 0) { \n "
" std::cout << p ? *p : 0; \n " // Due to operator precedence, this is equivalent to: (std::cout << p) ? *p : 0;
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Possible null pointer dereference if the default parameter value is used: p \n " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" std::cout << (p ? *p : 0); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" std::cout << p; \n "
2013-02-28 08:45:21 +01:00
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" std::cout << (p && p[0] ? *p : 42); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void isEmpty(int *p = 0) { \n "
2013-04-15 19:00:15 +02:00
" return p && *p; \n "
2013-02-28 08:45:21 +01:00
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void g(int *p = 0) { \n "
2013-04-15 19:00:15 +02:00
" return !p || *p; \n "
2013-02-28 08:45:21 +01:00
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-04-25 09:25:56 +02:00
// bar may initialize p but be can't know for sure without knowing
// if p is passed in by reference and is modified by bar()
check ( " void f(int *p = 0) { \n "
" bar(p); \n "
" *p = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" printf( \" %d \" , p); \n "
" *p = 0; \n "
2015-02-01 15:05:00 +01:00
" } " , true ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning, inconclusive) Possible null pointer dereference if the default parameter value is used: p \n " , errout . str ( ) ) ;
2013-04-25 09:25:56 +02:00
// The init() function may or may not initialize p, but since the address
// of p is passed in, it's a good bet that p may be modified and
// so we should not report an error.
check ( " void f(int *p = 0) { \n "
" init(&p); \n "
" *p = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void init(int* &g); \n "
" void f(int *p = 0) { \n "
" init(p); \n "
" *p = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" if (p == 0) { \n "
" init(&p); \n "
" } \n "
" *p = 0; \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-25 09:25:56 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" if (p == 0) { \n "
" throw SomeException; \n "
" } \n "
" *p = 0; \n "
2015-01-31 20:12:02 +01:00
" } " , false , " test.cpp " , false ) ;
2013-04-25 09:25:56 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2014-05-22 19:48:00 +02:00
check ( " void foo(int *p = 0) { \n "
" int var1 = x ? *p : 5; \n "
" } " ) ;
2015-02-01 15:05:00 +01:00
ASSERT_EQUALS ( " [test.cpp:2]: (warning) Possible null pointer dereference if the default parameter value is used: p \n " , errout . str ( ) ) ;
2012-11-21 08:56:17 +01:00
}
2014-11-20 14:20:09 +01:00
void nullpointer_internal_error ( ) { // ticket #5080
2013-10-12 10:50:59 +02:00
check ( " struct A { unsigned int size; }; \n "
" struct B { struct A *a; }; \n "
" void f(struct B *b) { \n "
" unsigned int j; \n "
" for (j = 0; j < b[0].a->size; ++j) { \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-10-31 11:51:25 +01:00
} ;
REGISTER_TEST ( TestNullPointer )