#include 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); }