1  #include <stdio.h>
       2  
       3  struct st
       4  {
       5    char *str;
       6    int i;
       7  };
       8  
       9  int test_1 (struct st *p)
      10  {
      11    fprintf (stderr, "str: %s\n", p->str); /* { dg-message "pointer 'p' is dereferenced here" } */
      12    if (!p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
      13      return -1;
      14    return p->i;  
      15  }
      16  
      17  int test_2 (int flag_a, int flag_b, struct st *p)
      18  {
      19    if (flag_a)
      20      {
      21        int j = p->i; /* { dg-message "pointer 'p' is dereferenced here" } */
      22        if (flag_b && p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
      23  	return 1;
      24        return j;
      25      }
      26    return 2;
      27  }
      28  
      29  int test_3 (struct st *a, struct st *b)
      30  {
      31    if (!a)
      32      return b->i;
      33    if (!b)
      34      return a->i;
      35    return 0;
      36  }
      37  
      38  int test_4 (struct st *p)
      39  {
      40    int *q = &p->i;
      41    if (!p)
      42      return -1;
      43    return *q;  
      44  }
      45  
      46  void test_check_after_strlen (const char *str)
      47  {
      48    size_t len_a = __builtin_strlen (str); /* { dg-message "pointer 'str' is dereferenced here" } */
      49    size_t len_b = str ? __builtin_strlen (str) : 0; /* { dg-warning "check of 'str' for NULL after already dereferencing it" } */
      50  }
      51  
      52  void test_6 (struct st *a, struct st *b)
      53  {
      54    int diff = a->i - b->i; /* { dg-message "pointer 'b' is dereferenced here" } */
      55  
      56    /* ... */
      57  
      58    if (b) /* { dg-warning "check of 'b' for NULL after already dereferencing it" } */
      59      fprintf (stderr, "str: %s\n", b->str);
      60  }
      61  
      62  void test_check_after_strcmp (const char *s1, const char *s2)
      63  {
      64    if (!__builtin_strcmp (s1, s2)) /* { dg-message "pointer 's1' is dereferenced here" } */
      65      return;
      66  
      67    /* ... */
      68  
      69    if (s1) /* { dg-warning "check of 's1' for NULL after already dereferencing it" } */
      70      return;
      71  }
      72  
      73  void test_more_than_one_deref (struct st *p)
      74  {
      75    char *str = p->str; /* { dg-message "pointer 'p' is dereferenced here" } */
      76    int i = p->i;
      77    
      78    /* ... */
      79  
      80    if (p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
      81      return;
      82  
      83    /* ... */
      84  }
      85  
      86  void test_deref_under_another_name (struct st *p)
      87  {
      88    struct st *q = p;
      89    int i = q->i; /* { dg-message "pointer 'p' is dereferenced here" } */
      90  
      91    /* ... */
      92  
      93    if (p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
      94      return;
      95  
      96    /* ... */
      97  }
      98  
      99  void test_check_after_memcpy_src (struct st *dst, struct st *src)
     100  {
     101    __builtin_memcpy (dst, src, sizeof (struct st)); /* { dg-message "pointer 'src' is dereferenced here" } */
     102  
     103    /* ... */
     104  
     105    if (!src) /* { dg-warning "check of 'src' for NULL after already dereferencing it" } */
     106      return;
     107  
     108    /* ... */
     109  }
     110  
     111  void test_check_after_memcpy_dst (struct st *dst, struct st *src)
     112  {
     113    __builtin_memcpy (dst, src, sizeof (struct st)); /* { dg-message "pointer 'dst' is dereferenced here" } */
     114  
     115    /* ... */
     116  
     117    if (!dst) /* { dg-warning "check of 'dst' for NULL after already dereferencing it" } */
     118      return;
     119  
     120    /* ... */
     121  }
     122  
     123  void test_merger (int *p, int flag)
     124  {
     125    int x = *p;
     126    if (flag)
     127      __builtin_free (p);
     128    if (!flag)
     129      __builtin_free (p); /* { dg-bogus "double-'free'" } */
     130  }