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