2 * Copyright (C) 2014 Oracle.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
19 * This file is sort of like check_dereferences_param.c. In theory the one
20 * difference should be that the param is NULL it should still be counted as a
21 * free. But for now I don't handle that case.
25 #include "smatch_extra.h"
26 #include "smatch_slist.h"
32 static struct smatch_state
*unmatched_state(struct sm_state
*sm
)
34 if (parent_is_null_var_sym(sm
->name
, sm
->sym
))
39 static void set_ignore(struct sm_state
*sm
, struct expression
*mod_expr
)
41 if (sm
->sym
&& sm
->sym
->ident
&&
42 strcmp(sm
->sym
->ident
->name
, sm
->name
) == 0)
44 set_state(my_id
, sm
->name
, sm
->sym
, &ignore
);
47 void track_freed_param(struct expression
*expr
, struct smatch_state
*state
)
49 struct expression
*tmp
;
53 tmp
= get_assigned_expr(expr
);
57 param
= get_param_key_from_expr(expr
, NULL
, &key
);
60 if (param_was_set(expr
))
63 set_state_expr(my_id
, expr
, state
);
66 void track_freed_param_var_sym(const char *name
, struct symbol
*sym
,
67 struct smatch_state
*state
)
69 struct expression
*tmp
;
71 tmp
= get_assigned_expr_name_sym(name
, sym
);
73 track_freed_param(tmp
, state
);
75 if (get_param_num_from_sym(sym
) < 0)
78 * FIXME: some unpublished code made this apply to only '$' and I
79 * don't remember why I would do that. But there was probably
82 if (param_was_set_var_sym(name
, sym
))
85 set_state(my_id
, name
, sym
, state
);
88 static void return_freed_callback(int return_id
, char *return_ranges
,
89 struct expression
*returned_expr
,
91 const char *printed_name
,
94 if (strcmp(sm
->state
->name
, "freed") != 0)
97 if (on_atomic_dec_path())
100 sql_insert_return_states(return_id
, return_ranges
, PARAM_FREED
,
101 param
, printed_name
, "");
104 void check_frees_param_strict(int id
)
108 add_modification_hook(my_id
, &set_ignore
);
109 add_return_info_callback(my_id
, return_freed_callback
);
110 add_unmatched_state_hook(my_id
, &unmatched_state
);