1 #include <stdlib.h>
2 
3 struct ptr_wrapper
4 {
5   int *ptr;
6 };
7 
8 struct ptr_wrapper
test_1(void)9 test_1 (void)
10 {
11   struct ptr_wrapper r;
12   r.ptr = malloc (sizeof (int));
13   return r;
14 }
15 
16 struct ptr_wrapper
test_2(void)17 test_2 (void)
18 {
19   struct ptr_wrapper r, s;
20   r.ptr = malloc (sizeof (int));
21   s = r;
22   return s;
23 }
24 
25 struct nested
26 {
27   struct ptr_wrapper w;
28 };
29 
30 struct nested
test_3(void)31 test_3 (void)
32 {
33   struct nested n;
34   n.w.ptr = malloc (sizeof (int));
35   return n;
36 }
37 
test_4(void)38 void test_4 (void)
39 {
40   struct ptr_wrapper r;
41   r.ptr = malloc (sizeof (int)); /* { dg-message "allocated here" } */
42 } /* { dg-warning "leak of 'r.ptr'" } */
43 /* { dg-bogus "leak of '<unknown>'" "unknown leak" { target *-*-* } .-1 } */
44 
45 static struct ptr_wrapper __attribute__((noinline))
called_by_test_5a(void)46 called_by_test_5a (void)
47 {
48   struct ptr_wrapper r;
49   r.ptr = malloc (sizeof (int)); /* { dg-message "allocated here" } */
50   return r;
51 }
52 
test_5a(void)53 void test_5a (void)
54 {
55   struct ptr_wrapper q = called_by_test_5a ();
56 } /* { dg-warning "leak of 'q.ptr'" } */
57 
58 static struct ptr_wrapper __attribute__((noinline))
called_by_test_5b(void)59 called_by_test_5b (void)
60 {
61   struct ptr_wrapper r;
62   r.ptr = malloc (sizeof (int));
63   return r; /* { dg-warning "leak of '<return-value>.ptr'" } */
64   /* TODO: show the allocation point; improve above message.  */
65 }
66 
test_5b(void)67 void test_5b (void)
68 {
69   called_by_test_5b ();
70 }
71