| #include <stdlib.h> |
| #include "analyzer-decls.h" |
| |
| typedef struct _krb5_data { |
| char *data; |
| } krb5_data; |
| |
| void |
| test_1 (krb5_data inbuf, int flag) |
| { |
| free(inbuf.data); /* { dg-message "first 'free' here" } */ |
| free(inbuf.data); /* { dg-warning "double-'free' of 'inbuf.data'" } */ |
| } |
| |
| void |
| test_2 (krb5_data inbuf, int flag) |
| { |
| if (flag) { |
| free(inbuf.data); /* { dg-message "first 'free' here" } */ |
| } |
| free(inbuf.data); /* { dg-warning "double-'free' of 'inbuf.data'" } */ |
| } |
| |
| void |
| test_3 (krb5_data inbuf, int flag) |
| { |
| if (flag) { |
| free((char *)inbuf.data); /* { dg-message "first 'free' here" } */ |
| } |
| free((char *)inbuf.data); /* { dg-warning "double-'free' of 'inbuf.data'" } */ |
| } |
| |
| extern void unknown_fn (void *); |
| |
| void |
| test_4 (krb5_data inbuf) |
| { |
| unknown_fn (NULL); |
| free(inbuf.data); /* { dg-message "first 'free' here" } */ |
| free(inbuf.data); /* { dg-warning "double-'free' of 'inbuf.data'" } */ |
| } |
| |
| void |
| test_5 (krb5_data inbuf) |
| { |
| unknown_fn (&inbuf); |
| free(inbuf.data); /* { dg-message "first 'free' here" } */ |
| free(inbuf.data); /* { dg-warning "double-'free' of 'inbuf.data'" "inbuf.data" } */ |
| /* { dg-bogus "double-'free' of 'inbuf'" "inbuf" { target *-*-* } .-1 } */ |
| } |
| |
| typedef struct _padded_krb5_data { |
| int pad; |
| char *data; |
| } padded_krb5_data; |
| |
| void |
| test_6 (padded_krb5_data inbuf) |
| { |
| unknown_fn (&inbuf.data); |
| free((char *)inbuf.data); /* { dg-message "first 'free' here" } */ |
| free((char *)inbuf.data); /* { dg-warning "double-'free' of 'inbuf.data'" "inbuf.data" } */ |
| } |
| |
| void |
| test_7 (padded_krb5_data inbuf) |
| { |
| unknown_fn (&inbuf.data); |
| free((char *)inbuf.data); |
| |
| unknown_fn (&inbuf.data); |
| free((char *)inbuf.data); |
| } |
| |
| void |
| test_8 (padded_krb5_data inbuf, int flag) |
| { |
| if (flag) |
| { |
| unknown_fn (&inbuf.data); |
| free((char *)inbuf.data); |
| } |
| /* Should have two enodes, one for the explicit "freed" state, and one |
| for the implicit "start" state. */ |
| __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */ |
| |
| unknown_fn (&inbuf.data); |
| |
| /* Should have just one enode, for the implicit "start" state. */ |
| __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ |
| } |