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
;
52 while ((tmp
= get_assigned_expr(expr
))) {
53 expr
= strip_expr(tmp
);
58 if (get_param_num(expr
) < 0)
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 if (get_param_num_from_sym(sym
) < 0)
72 * FIXME: some unpublished code made this apply to only '$' and I
73 * don't remember why I would do that. But there was probably
76 if (param_was_set_var_sym(name
, sym
))
79 set_state(my_id
, name
, sym
, state
);
82 static void param_freed_info(int return_id
, char *return_ranges
, struct expression
*expr
)
86 const char *param_name
;
88 if (on_atomic_dec_path())
91 FOR_EACH_MY_SM(my_id
, __get_cur_stree(), sm
) {
92 if (strcmp(sm
->state
->name
, "freed") != 0)
95 param
= get_param_key_from_sm(sm
, NULL
, ¶m_name
);
99 sql_insert_return_states(return_id
, return_ranges
, PARAM_FREED
,
100 param
, param_name
, "");
101 } END_FOR_EACH_SM(sm
);
104 void check_frees_param_strict(int id
)
108 add_modification_hook(my_id
, &set_ignore
);
109 add_split_return_callback(¶m_freed_info
);
110 add_unmatched_state_hook(my_id
, &unmatched_state
);