blob: fd1ecbb7005b0ccfc9a4f907b24760b24c006eb6 [file] [log] [blame]
/* Verify that the analyzer correctly purges state when it sees a call to
an unknown function. */
#include <stdlib.h>
/* Verify fix for false-positive when checking for CVE-2005-1689. */
typedef struct _krb5_data {
char *data;
} krb5_data;
extern void krb5_read_message(krb5_data *buf);
void
test_1 (krb5_data inbuf)
{
free(inbuf.data);
krb5_read_message(&inbuf);
free(inbuf.data); /* { dg-bogus "double-'free'" } */
}
/* Verify that __pure__ functions are treated as not having side-effects. */
extern int called_by_test_1a (void *)
__attribute__ ((__pure__));
void test_1a (krb5_data inbuf)
{
free (inbuf.data);
called_by_test_1a (&inbuf);
free (inbuf.data); /* { dg-warning "double-'free'" } */
}
/* Verify that global pointers can be affected by an unknown function. */
void *global_ptr;
extern void unknown_side_effects (void);
void test_2 (void)
{
free (global_ptr);
unknown_side_effects ();
free (global_ptr);
}
extern void called_by_test_3 (void *);
void test_3a (void)
{
void *ptr = malloc (1024);
called_by_test_3 (ptr);
} /* { dg-bogus "leak" } */
void test_3b (void)
{
krb5_data k;
k.data = malloc (1024);
called_by_test_3 (&k);
} /* { dg-bogus "leak" } */
/* Verify that we traverse the graph of regions that are reachable from
the call. */
struct foo
{
struct foo *next;
int *ptr;
};
/* First, without a call to an unknown function. */
void test_4a (void)
{
struct foo node_a;
struct foo node_b;
node_a.next = &node_b;
node_b.ptr = malloc (sizeof (int));
global_ptr = &node_a;
*node_b.ptr = 42; /* { dg-warning "possibly-NULL" "possibly-NULL" } */
/* Although there's a chain of pointers to the allocation, pointed to
by global_ptr, the chain goes through the stack frame and thus
there's a leak when it is popped. */
} /* { dg-warning "leak of 'node_b.ptr'" } */
/* With a call to an unknown function. */
void test_4b (void)
{
struct foo node_a;
struct foo node_b;
node_a.next = &node_b;
node_b.ptr = malloc (sizeof (int));
global_ptr = &node_a;
unknown_side_effects (); /* everything potentially visible through global_ptr. */
*node_b.ptr = 42; /* { dg-bogus "possibly-NULL" } */
} /* { dg-bogus "leak" } */
extern void called_by_test_5 (const char *);
void test_5 (void)
{
called_by_test_5 ("???");
}
extern void called_by_test_6 (const struct foo *);
void test_6 (void)
{
struct foo node;
node.next = NULL;
node.ptr = malloc (sizeof (int));
/* This is a const ptr, but struct foo's ptr is non-const,
so we ought to assume it could be written to. */
called_by_test_6 (&node);
} /* { dg-bogus "leak" } */
/* TODO: things reachable from "outside" i.e. by params to caller to entrypoint. */