2010-10-31 11:51:25 +01:00
/*
* Cppcheck - A tool for static C / C + + code analysis
2013-01-01 17:29:08 +01:00
* Copyright ( C ) 2007 - 2013 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"
# include <sstream>
extern std : : ostringstream errout ;
2011-10-13 20:53:06 +02:00
class TestNullPointer : public TestFixture {
2010-10-31 11:51:25 +01:00
public :
TestNullPointer ( ) : TestFixture ( " TestNullPointer " )
{ }
private :
2011-10-13 20:53:06 +02:00
void run ( ) {
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 ( nullpointer8 ) ;
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
2011-11-26 21:15:16 +01:00
TEST_CASE ( nullpointer14 ) ;
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-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-01-31 15:49:34 +01:00
TEST_CASE ( crash1 ) ;
2012-11-21 08:56:17 +01:00
TEST_CASE ( functioncallDefaultArguments ) ;
2010-10-31 11:51:25 +01:00
}
2013-04-15 19:00:15 +02: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 ( " " ) ;
Settings settings ;
2013-02-02 15:46:29 +01:00
settings . addEnabled ( " warning " ) ;
2011-10-09 15:09:02 +02:00
settings . inconclusive = inconclusive ;
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 ) ) ;
2010-10-31 11:51:25 +01:00
tokenizer . simplifyTokenList ( ) ;
2013-04-15 19:00:15 +02:00
const std : : string str2 ( tokenizer . tokens ( ) - > stringifyList ( 0 , true ) ) ;
if ( verify & & str1 ! = str2 )
2013-04-16 16:54:19 +02:00
warn ( ( " Unsimplified code in test case. It looks like this test "
" should either be cleaned up or moved to TestTokenizer or "
" TestSimplifyTokens instead. \n str1= " + str1 + " \n str2= " + str2 ) . c_str ( ) ) ;
2013-04-15 19:00:15 +02:00
2010-10-31 11:51:25 +01:00
checkNullPointer . nullConstantDereference ( ) ;
checkNullPointer . executionPaths ( ) ;
}
2011-10-13 20:53:06 +02: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 "
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: 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..
{
const char code [ ] = " void foo(int x, const Token *tok) { \n "
" if (x == 123) { \n "
" while (tok) tok = tok->next(); \n "
" } \n "
" tok->str(); \n "
" } \n " ;
check ( code , false ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( code , true ) ;
2013-04-07 03:41:02 +02:00
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-09 15:09:02 +02:00
}
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
}
2011-10-13 20:53:06 +02: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
}
2011-10-13 20:53:06 +02: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
2011-10-13 20:53:06 +02: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 "
" if (!abc) \n "
" ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
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: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 "
" } " ) ;
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 "
2013-03-20 15:36:16 +01:00
" } " ) ;
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
// #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
// false positives when there are macros
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
2011-10-13 20:53:06 +02: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 "
2013-03-20 15:36:16 +01:00
" } " ) ;
2013-04-07 03:41:02 +02:00
TODO_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 "
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 "
" 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
" } " ) ;
2011-10-02 19:27:18 +02:00
TODO_ASSERT_EQUALS ( " error " , " " , errout . str ( ) ) ;
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
// #3023 - checked deref
check ( " void f(struct ABC *abc) { \n "
" WARN_ON(!abc || abc->x == 0); \n "
" if (!abc) { } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(struct ABC *abc) { \n "
" WARN_ON(!abc || abc->x == 7); \n "
" if (!abc) { } \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-12-18 13:33:23 +01:00
// false positives when there are macros
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
}
2011-10-13 20:53:06 +02: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..
2011-10-13 20:53:06 +02: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
{
const char code [ ] = " static void foo(int x) \n "
" { \n "
" 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 ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (error) Possible null pointer dereference: abc \n " , errout . str ( ) ) ;
}
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 "
" } " ) ;
TODO_ASSERT_EQUALS ( " error " , " " , errout . str ( ) ) ;
}
2010-10-31 11:51:25 +01:00
}
2010-12-26 13:38:16 +01:00
// Ticket #2350
2011-10-13 20:53:06 +02:00
void nullpointerExecutionPathsLoop ( ) {
2010-12-26 13:38:16 +01:00
// No false positive:
check ( " void foo() { \n "
" int n; \n "
" int *argv32; \n "
" 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 "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:11]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
2010-12-26 13:38:16 +01:00
}
2011-10-13 20:53:06 +02: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 ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void nullpointer8 ( ) {
2010-10-31 11:51:25 +01:00
check ( " void foo() \n "
" { \n "
" char const * x = 0; \n "
" strdup(x); \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: x \n " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02: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 ) ;
2011-03-24 01:19:32 +01:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2010-10-31 11:51:25 +01:00
}
2011-10-13 20:53:06 +02: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
}
2011-10-13 20:53:06 +02: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
}
2012-08-25 12:00:25 +02:00
void nullpointer12 ( ) { // ticket #2470, #4035
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
2011-10-16 12:54:58 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
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 ( ) ) ;
}
2011-11-26 21:15:16 +01:00
void nullpointer14 ( ) {
check ( " void foo() \n "
" { \n "
" strcpy(bar, 0); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-11-26 21:15:16 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
check ( " void foo() \n "
" { \n "
" memcmp(bar(xyz()), 0, 123); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-11-26 21:15:16 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2011-11-28 21:32:07 +01:00
check ( " void foo(const char *s) \n "
" { \n "
" char *p = malloc(100); \n "
" frexp(1.0, p); \n "
" char *q = 0; \n "
" frexp(1.0, q); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-11-28 21:32:07 +01:00
ASSERT_EQUALS ( " [test.cpp:6]: (error) Possible null pointer dereference: q \n " , errout . str ( ) ) ;
2011-11-26 21:15:16 +01:00
}
2012-01-28 08:06:03 +01:00
void nullpointer15 ( ) { // #3560
check ( " void f() { \n "
" char *p = 0; \n "
" if (x) p = \" abcd \" ; \n "
" return p ? f(*p) : f(0); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2012-02-13 19:46:45 +01:00
void nullpointer16 ( ) { // #3591
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 ( ) ) ;
}
2012-03-07 20:31:23 +01:00
void nullpointer17 ( ) { // #3567
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 ( ) ) ;
}
2012-04-01 15:54:41 +02:00
void nullpointer18 ( ) { // #1927
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 ) ;
2012-04-01 15:54:41 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
}
2012-05-16 09:56:39 +02:00
void nullpointer19 ( ) { // #3811
check ( " int foo() { \n "
" perror(0); \n "
" } " , true ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2012-05-31 18:41:00 +02:00
void nullpointer20 ( ) { // #3807
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 "
" } " ) ;
TODO_ASSERT_EQUALS ( " error " , " " , errout . str ( ) ) ;
}
2012-09-23 09:20:16 +02:00
void nullpointer21 ( ) { // #4038 - fp: if (x) p=q; else return;
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 ( ) ) ;
}
2013-03-19 08:47:05 +01:00
void nullpointer23 ( ) { // #4665
check ( " void f(){ \n "
" char *c = NULL; \n "
" char cBuf[10]; \n "
" sprintf(cBuf, \" %s \" , c ? c : \" 0 \" ); \n "
" } " ) ;
TODO_ASSERT_EQUALS ( " " , " [test.cpp:4]: (error) Possible null pointer dereference: c \n " , errout . str ( ) ) ;
}
2013-04-03 10:27:08 +02:00
void nullpointer_cast ( ) { // #4692
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 ( ) ) ;
}
2012-04-30 12:36:41 +02:00
void nullpointer_castToVoid ( ) { // #3771
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
2011-10-13 20:53:06 +02: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 "
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-11-04 21:22:29 +01:00
check ( " void foo(char *p) { \n "
" if (p == NULL) { \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-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 "
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-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 "
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-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 "
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: 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 ) ;
ASSERT_EQUALS ( " [test.cpp:5] -> [test.cpp:2]: (warning, inconclusive) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n " , errout . str ( ) ) ;
}
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 "
" } " ) ;
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 "
" } " ) ;
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 "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
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 "
" } " ) ;
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 "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// check, and use
check ( " void f() { \n "
" char *p; \n "
" if (p == 0 && (*p = 0)) { \n "
" return; \n "
" } \n "
" } " ) ;
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 "
" } " ) ;
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 "
" } " ) ;
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 "
" } " ) ;
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 "
" } " ) ;
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 "
" } " ;
check ( code ) ; // non-inconclusive
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( code , true ) ; // 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 "
2013-03-20 15:36:16 +01:00
" } " ) ;
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 ( ) ) ;
2010-10-31 11:51:25 +01:00
}
2010-12-26 19:29:58 +01:00
// Test CheckNullPointer::nullConstantDereference
2011-10-13 20:53:06 +02:00
void nullConstantDereference ( ) {
2010-12-26 19:29:58 +01:00
// Ticket #2090
check ( " void foo() { \n "
2013-04-15 19:00:15 +02:00
" strcpy(0, \" abcd \" ); \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 ( ) ) ;
2011-01-06 08:12:34 +01:00
2012-02-11 12:26:48 +01:00
// Ticket #1171
check ( " void foo(void* bar) { \n "
" if(strcmp(0, bar) == 0) \n "
" func(); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2011-01-06 08:12:34 +01:00
// Ticket #2413 - it's ok to pass NULL to fflush
check ( " void foo() { \n "
" fflush(NULL); \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2011-01-06 08:12:34 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-02 18:24:45 +02:00
// Ticket #3126 - don't confuse member function with standard function
check ( " void f() { \n "
" image1.fseek(0, SEEK_SET); \n "
2012-04-30 12:36:41 +02:00
" } " , true ) ;
2011-10-02 18:24:45 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
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 ) ;
2012-01-25 15:16:22 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2013-06-07 06:37:53 +02:00
check ( " void f(int x) { \n " // #4809 - passing "NULL"
" itoa(x,NULL,10); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Null pointer dereference \n " , errout . str ( ) ) ;
2010-12-26 19:29:58 +01:00
}
2011-10-13 20:53:06 +02: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
2011-10-13 20:53:06 +02: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 ( ) ) ;
}
2011-10-13 20:53:06 +02: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
2011-10-13 20:53:06 +02: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
}
2011-10-13 20:53:06 +02: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 "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: iVal \n " , 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
void nullpointer_in_return ( ) {
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
void nullpointer_in_typeid ( ) {
// 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
}
2011-11-07 21:10:21 +01:00
void nullpointer_in_for_loop ( ) {
// 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
void nullpointerDelete ( ) {
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
void nullpointerExit ( ) {
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
2012-01-25 15:16:22 +01:00
void nullpointerStdString ( ) {
check ( " void f(std::string s1) { \n "
" void* p = 0; \n "
" s1 = 0; \n "
" std::string s2 = 0; \n "
" 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 ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Null pointer dereference \n "
" [test.cpp:4]: (error) Null pointer dereference \n "
" [test.cpp:5]: (error) Null pointer dereference \n "
" [test.cpp:6]: (error) Null pointer dereference \n "
" [test.cpp:7]: (error) Possible null pointer dereference: p \n "
" [test.cpp:8]: (error) Possible null pointer dereference: p \n "
" [test.cpp:9]: (error) Possible null pointer dereference: p \n "
" [test.cpp:10]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
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 ( ) ) ;
2012-01-25 15:16:22 +01:00
}
2012-03-16 17:24:03 +01:00
void nullpointerStdStream ( ) {
check ( " void f(std::ifstream& is) { \n "
" char* p = 0; \n "
" is >> p; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: p \n " , errout . str ( ) ) ;
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 ) ;
2012-03-16 17:24:03 +01:00
TODO_ASSERT_EQUALS ( " [test.cpp:3]: (error) Possible null pointer dereference: p \n "
" [test.cpp:4]: (error) Possible null pointer dereference: p \n "
2013-04-07 03:41:02 +02:00
" [test.cpp:6] -> [test.cpp:5]: (warning) Possible null pointer dereference: q - otherwise it is redundant to check it against null. \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 "
" } " ) ;
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 "
" [test.cpp:5] -> [test.cpp:2]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null. \n "
" [test.cpp:6] -> [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 ( ) ) ;
2012-03-16 17:24:03 +01:00
}
2011-12-25 17:01:45 +01:00
void functioncall ( ) { // #3443 - function calls
// 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
2013-07-15 21:57:58 +02:00
void functioncalllibrary ( ) {
Settings settings ;
Tokenizer tokenizer ( & settings , this ) ;
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 ;
Library : : Argument arg = { 0 } ;
library . functionArgument [ " x " ] [ 1 ] = arg ;
library . functionArgument [ " x " ] [ 2 ] = arg ;
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 ;
Library : : Argument arg = { 0 } ;
library . functionArgument [ " x " ] [ 1 ] = arg ;
library . functionArgument [ " x " ] [ 2 ] = arg ;
library . functionArgument [ " x " ] [ 1 ] . nullpointer = true ;
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 ;
Library : : Argument arg = { 0 } ;
library . functionArgument [ " x " ] [ 1 ] = arg ;
library . functionArgument [ " x " ] [ 2 ] = arg ;
library . functionArgument [ " x " ] [ 2 ] . uninitdata = true ;
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
void functioncallDefaultArguments ( ) {
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 "
" } " ) ;
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 "
" } " ) ;
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 "
" } " ) ;
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 "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Possible null pointer dereference if the default parameter value is used: p \n " , errout . str ( ) ) ;
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 "
" } " ) ;
ASSERT_EQUALS ( " " , 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 && 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 "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Possible null pointer dereference if the default parameter value is used: p \n " , errout . str ( ) ) ;
// 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 "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f(int *p = 0) { \n "
" if (p == 0) { \n "
" throw SomeException; \n "
" } \n "
" *p = 0; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-11-21 08:56:17 +01:00
}
2012-01-31 15:49:34 +01:00
void crash1 ( ) {
check ( " int f() { \n "
" return if \n "
" } " ) ;
}
2010-10-31 11:51:25 +01:00
} ;
REGISTER_TEST ( TestNullPointer )