blob: d9704dee6f22b3a40477678b6e7e08e93732bf84 (
plain)
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
#include <stdlib.h>
struct st
{
void *m_f;
};
struct node
{
struct node *m_next;
};
extern void unknown_fn (void *);
extern void const_unknown_fn (const void *);
void
test_1 (struct st *p, struct st *q)
{
p->m_f = malloc (1024);
q->m_f = NULL; /* { dg-bogus "leak" } */
free (p->m_f);
}
void
test_2 (void)
{
struct st s;
s.m_f = malloc (1024);
unknown_fn (&s);
free (s.m_f);
}
void
test_3 (void)
{
struct st s;
s.m_f = malloc (1024);
const_unknown_fn (&s);
free (s.m_f);
}
void
test_4 (void)
{
struct st s;
s.m_f = malloc (1024);
unknown_fn (&s);
} /* { dg-bogus "leak" } */
void
test_5 (void)
{
struct st s;
s.m_f = malloc (1024);
/* s is const, but the pointer could still be freed; hence not a leak. */
const_unknown_fn (&s);
} /* { dg-bogus "leak" } */
void
test_6 (void)
{
struct st s;
s.m_f = malloc (1024);
} /* { dg-warning "leak" } */
struct st
test_7 (void)
{
struct st s;
s.m_f = malloc (1024);
return s;
} /* { dg-bogus "leak" } */
struct node *
test_8 (void)
{
struct node *n1 = malloc (sizeof (struct node));
if (!n1)
return NULL;
n1->m_next = malloc (sizeof (struct node));
return n1;
}
void
test_9 (void)
{
struct node *n1 = malloc (sizeof (struct node));
if (!n1)
return;
n1->m_next = malloc (sizeof (struct node));
/* Could free n1 and n1->m_next. */
unknown_fn (n1);
}
void
test_10 (void)
{
struct node *n1 = malloc (sizeof (struct node));
if (!n1)
return;
n1->m_next = malloc (sizeof (struct node));
/* Could free n1->m_next, but not n1. */
const_unknown_fn (n1); /* { dg-warning "leak of 'n1'" } */
}
void
test_11 (void)
{
struct node *n1 = malloc (sizeof (struct node));
if (!n1)
return;
n1->m_next = malloc (sizeof (struct node));
/* Could free n1->m_next, but not n1. */
unknown_fn (n1->m_next); /* { dg-warning "leak of 'n1'" } */
}
void
test_12a (void)
{
int *ip = malloc (sizeof (int));
*ip = 42; /* { dg-warning "dereference of possibly-NULL 'ip'" } */
free (ip);
}
void
test_12b (void)
{
int *ip = malloc (sizeof (int));
unknown_fn (ip);
/* Might not be a null-deref, as unknown_fn could abort on NULL. */
*ip = 42;
free (ip);
}
void
test_12c (void)
{
int *ip = malloc (sizeof (int));
/* Might not be a null-deref, as const_unknown_fn could abort on NULL.
Right now we don't have a great way of handling this. */
const_unknown_fn (ip);
*ip = 42; /* { dg-bogus "dereference of possibly-NULL 'ip'" "" { xfail *-*-* } } */
free (ip);
}
|