Search code examples
cnullwarningsdereferencecppcheck

cppcheck "Possible null pointer dereference". False positive or a bug?


I have this C code:

#include <stdio.h>                                                              
#include <stdlib.h>                                                             
                                                                                
typedef struct {                                                                
    int value;                                                                  
} pointer_t;                                                                    
                                                                                
int some_func (pointer_t *p)                                                    
{                                                                               
    int v  =  (           rand () ) ?  99 :                                     
              (                !p ) ?   0 :                                     
              ( p->value % 2 == 0 ) ?   1 : /* << This is line 12 */ 
                                       -1 ;           
                                                                                
    return v;                                                                   
}                                                                               
                                                                                
int main () {                                                                   
    pointer_t p = { .value = 7 };                                               
                                                                                
    printf ("With a pointer : %d\n", some_func (&p));                           
    printf ("With a NULL    : %d\n", some_func (NULL));                         
} 

When I run:

cppcheck prog.c

I get the following warning:

[prog.c:12]: (warning) Possible null pointer dereference: p

But I don't think there is a bug in my code: the previous line already checks the case when p is NULL, so in line 12 p must be non-NULL

Is this a false positive in cppcheck, or is there a corner case I haven't checked?

Edit

If it helps, these are some checks I did:

/* Generates a warning */
v  =  (           rand () ) ?  99 :
      (                !p ) ?   0 : 
      ( p->value % 2 == 0 ) ?   1 : 
                               -1 ;

/* Does not generate a warning */
v  =  (        p == NULL  ) ?   0 : 
      ( p->value % 2 == 0 ) ?   1 : 
                               -1 ;

/* Does not generate a warning */
if ( rand () )
    v = 99; 
else if (!p)
    v = 0;
else if (p->value % 2 == 0)
    v =  1;  
else
    v = -1; 

/* Generates a warning */
v  =  (           rand () ) ?  99 :
      (         p == NULL ) ?   0 : 
      ( p->value % 2 == 0 ) ?   1 : 
                               -1 ;

Solution

  • It looks like a false positive, because cppcheck doesn't seem to follow all branches.

    This is basically:

     if (rand())
        return 99;
     else if(!p)
        return 0;
     else if(p->value %2 == 0)
        return 1;
     else
        return -1;